From a08f75b0737c86d51bbc91538e78b1455eb2cae7 Mon Sep 17 00:00:00 2001
From: Binh-Minh Ribler <bmribler@hdfgroup.org>
Date: Sun, 6 Apr 2014 17:36:15 -0500
Subject: [svn-r24969] Description:     - Added wrappers to H5Object for
 H5Iget_name() to get object's name         ssize_t getObjName(char *obj_name,
 size_t buf_size = 0) const;         ssize_t getObjName(H5std_string&
 obj_name, size_t len = 0) const;         H5std_string getObjName() const;    
 - Added tests tobject.cpp     - Added to various cleanup_* functions in tests
 to remove generated files     - Added an overload H5I_type_t getHDFObjType()
 to get object's type Platforms tested:     Linux/ppc64 (ostrich)     Linux/32
 2.6 (jam)     SunOS 5.11 (emu) with gmake

---
 c++/src/H5Attribute.cpp   |   6 +-
 c++/src/H5Attribute.h     |   2 +-
 c++/src/H5IdComponent.cpp |  22 +++-
 c++/src/H5IdComponent.h   |   3 +
 c++/src/H5Object.cpp      | 112 +++++++++++++++++++
 c++/src/H5Object.h        |   8 +-
 c++/test/Makefile.am      |   4 +-
 c++/test/Makefile.in      |   9 +-
 c++/test/dsets.cpp        |  32 +++---
 c++/test/h5cpputil.h      |   2 +
 c++/test/tattr.cpp        |   8 +-
 c++/test/tcompound.cpp    |   4 +-
 c++/test/tdspl.cpp        |   5 +-
 c++/test/testhdf5.cpp     |  71 +++++++-----
 c++/test/tfile.cpp        |   1 +
 c++/test/tfilter.cpp      |   2 +-
 c++/test/tobject.cpp      | 269 ++++++++++++++++++++++++++++++++++++++++++++++
 c++/test/tvlstr.cpp       |  12 +--
 18 files changed, 498 insertions(+), 74 deletions(-)
 create mode 100644 c++/test/tobject.cpp

diff --git a/c++/src/H5Attribute.cpp b/c++/src/H5Attribute.cpp
index 9554f95..4625c2c 100644
--- a/c++/src/H5Attribute.cpp
+++ b/c++/src/H5Attribute.cpp
@@ -327,7 +327,7 @@ ssize_t Attribute::getName(char* attr_name, size_t buf_size) const
     {
 	throw AttributeIException("Attribute::getName", "Attribute must have a name, name length is 0");
     }
-
+    // Return length of the name
     return(name_size);
 }
 
@@ -357,7 +357,7 @@ H5std_string Attribute::getName() const
     {
 	throw AttributeIException("Attribute::getName", "Attribute must have a name, name length is 0");
     }
-    // If attribute's name exists, calls C routine again to get it
+    // Attribute's name exists, retrieve it
     else if (name_size > 0)
     {
         char* name_C = new char[name_size+1];  // temporary C-string
@@ -391,7 +391,7 @@ H5std_string Attribute::getName() const
 // Programmer	Binh-Minh Ribler - Nov, 2001
 // Modification
 //	Mar 2014 - BMR
-//		Revised to allow buf_size to be skipped
+//		Revised to allow the argument "len" to be skipped
 //--------------------------------------------------------------------------
 ssize_t Attribute::getName(H5std_string& attr_name, size_t len) const
 {
diff --git a/c++/src/H5Attribute.h b/c++/src/H5Attribute.h
index 8332632..8ec04af 100644
--- a/c++/src/H5Attribute.h
+++ b/c++/src/H5Attribute.h
@@ -39,7 +39,7 @@ class H5_DLLCPP Attribute : public AbstractDs, public IdComponent {
 
 	// Gets the name of this attribute.
 	ssize_t getName(char* attr_name, size_t buf_size = 0) const;
-	ssize_t getName(H5std_string& attr_name, size_t buf_size = 0) const;
+	ssize_t getName(H5std_string& attr_name, size_t len = 0) const;
 	H5std_string getName() const;
 
 	// Gets a copy of the dataspace for this attribute.
diff --git a/c++/src/H5IdComponent.cpp b/c++/src/H5IdComponent.cpp
index cdf4272..99a8dc4 100644
--- a/c++/src/H5IdComponent.cpp
+++ b/c++/src/H5IdComponent.cpp
@@ -130,7 +130,7 @@ int IdComponent::getCounter() const
 }
 
 //--------------------------------------------------------------------------
-// Function:	hdfObjectType
+// Function:	getHDFObjType (static)
 ///\brief	Given an id, returns the type of the object.
 ///\return	a valid HDF object type, which may be one of the following:
 ///		\li \c H5I_FILE
@@ -155,6 +155,26 @@ H5I_type_t IdComponent::getHDFObjType(const hid_t obj_id)
 }
 
 //--------------------------------------------------------------------------
+// Function:	getHDFObjType
+///\brief	Returns the type of the object.  It is an overloaded function
+///		of the above function.
+///\return	a valid HDF object type, which may be one of the following:
+///		\li \c H5I_FILE
+///		\li \c H5I_GROUP
+///		\li \c H5I_DATATYPE
+///		\li \c H5I_DATASPACE
+///		\li \c H5I_DATASET
+///		\li \c H5I_ATTR
+///		\li or \c H5I_BADID, if no valid type can be determined or the
+///				input object id is invalid.
+// Programmer   Binh-Minh Ribler - Mar, 2014
+//--------------------------------------------------------------------------
+H5I_type_t IdComponent::getHDFObjType() const
+{
+    return(getHDFObjType(getId()));
+}
+
+//--------------------------------------------------------------------------
 // Function:	IdComponent::operator=
 ///\brief	Assignment operator.
 ///\param	rhs - IN: Reference to the existing object
diff --git a/c++/src/H5IdComponent.h b/c++/src/H5IdComponent.h
index ca9352d..3208a39 100644
--- a/c++/src/H5IdComponent.h
+++ b/c++/src/H5IdComponent.h
@@ -46,6 +46,9 @@ class H5_DLLCPP IdComponent {
 	// Returns an HDF5 object type, given the object id.
 	static H5I_type_t getHDFObjType(const hid_t obj_id);
 
+	// Returns an HDF5 object type of this object.
+	H5I_type_t getHDFObjType() const;
+
 	// Assignment operator.
 	IdComponent& operator=( const IdComponent& rhs );
 
diff --git a/c++/src/H5Object.cpp b/c++/src/H5Object.cpp
index 1d96f2e..94b03ab 100644
--- a/c++/src/H5Object.cpp
+++ b/c++/src/H5Object.cpp
@@ -31,6 +31,7 @@
 #include "H5File.h"
 #include "H5DataSet.h"
 #include "H5Attribute.h"
+#include "H5private.h"		// for HDmemset
 
 #ifndef H5_NO_NAMESPACE
 namespace H5 {
@@ -53,6 +54,117 @@ H5Object::H5Object() : H5Location() {}
 H5Object::H5Object( const hid_t object_id ) : H5Location( object_id ) {}
 
 //--------------------------------------------------------------------------
+// Function:    getObjName
+///\brief       Given an id, returns the type of the object.
+///\return      The name of the object
+// Programmer   Binh-Minh Ribler - Mar, 2014
+//--------------------------------------------------------------------------
+ssize_t H5Object::getObjName(char *obj_name, size_t buf_size) const
+{
+    // H5Iget_name will get buf_size-1 chars of the name to null terminate it
+    ssize_t name_size = H5Iget_name(getId(), obj_name, buf_size);
+
+    // If H5Iget_name returns a negative value, raise an exception
+    if (name_size < 0)
+    {
+        throw Exception(inMemFunc("getObjName"), "H5Iget_name failed");
+    }
+    else if (name_size == 0)
+    {
+        throw Exception(inMemFunc("getObjName"), "Object must have a name, but name length is 0");
+    }
+    // Return length of the name
+    return(name_size);
+}
+
+//--------------------------------------------------------------------------
+// Function:    H5Object::getObjName
+///\brief       Returns the name of this object as an \a H5std_string.
+///\return      Name of the object
+///\exception   H5::Exception
+// Programmer   Binh-Minh Ribler - Mar, 2014
+// Modification
+//--------------------------------------------------------------------------
+H5std_string H5Object::getObjName() const
+{
+    H5std_string obj_name(""); // object name to return
+
+    // Preliminary call to get the size of the object name
+    ssize_t name_size = H5Iget_name(getId(), NULL, (size_t)0);
+
+    // If H5Iget_name failed, throw exception
+    if (name_size < 0)
+    {
+        throw Exception(inMemFunc("getObjName"), "H5Iget_name failed");
+    }
+    else if (name_size == 0)
+    {
+        throw Exception(inMemFunc("getObjName"), "Object must have a name, but name length is 0");
+    }
+    // Object's name exists, retrieve it
+    else if (name_size > 0)
+    {
+        char* name_C = new char[name_size+1];  // temporary C-string
+        HDmemset(name_C, 0, name_size+1); // clear buffer
+
+        // Use overloaded function
+        name_size = getObjName(name_C, name_size+1);
+
+        // Convert the C object name to return
+        obj_name = name_C;
+
+        // Clean up resource
+        delete []name_C;
+    }
+    // Return object's name
+    return(obj_name);
+}
+
+//--------------------------------------------------------------------------
+// Function:    H5Object::getObjName
+///\brief       Gets the name of this object, returning its length.
+///\param       obj_name - OUT: Buffer for the name string as \a H5std_string
+///\param       len  -  IN: Desired length of the name, default to 0
+///\return      Actual length of the object name
+///\exception   H5::Exception
+///\par Description
+///             This function retrieves the object's name as an std string.
+///             buf_size can specify a specific length or default to 0, in
+///             which case the entire name will be retrieved.
+// Programmer   Binh-Minh Ribler - Mar, 2014
+//--------------------------------------------------------------------------
+ssize_t H5Object::getObjName(H5std_string& obj_name, size_t len) const
+{
+    ssize_t name_size = 0;
+
+    // If no length is provided, get the entire object name
+    if (len == 0)
+    {
+        obj_name = getObjName();
+        name_size = obj_name.length();
+    }
+    // If length is provided, get that number of characters in name
+    else
+    {
+        char* name_C = new char[len+1];  // temporary C-string
+        HDmemset(name_C, 0, len+1); // clear buffer
+
+        // Use overloaded function
+        name_size = getObjName(name_C, len+1);
+
+        // Convert the C object name to return
+        obj_name = name_C;
+
+        // Clean up resource
+        delete []name_C;
+    }
+    // Otherwise, keep obj_name intact
+
+    // Return name size
+    return(name_size);
+}
+
+//--------------------------------------------------------------------------
 // Function:	H5Object copy constructor
 ///\brief	Copy constructor: makes a copy of the original H5Object
 ///		instance.
diff --git a/c++/src/H5Object.h b/c++/src/H5Object.h
index 5c2ef98..5576d13 100644
--- a/c++/src/H5Object.h
+++ b/c++/src/H5Object.h
@@ -33,7 +33,7 @@
 //		H5Object is H5File is not an HDF5 object, and renaming H5Object
 //		to H5Location will risk breaking user applications.
 //		-BMR
-
+//	Apr 2, 2014: Added wrapper getObjName for H5Iget_name 
 #ifndef H5_NO_NAMESPACE
 namespace H5 {
 #endif
@@ -50,6 +50,12 @@ class H5_DLLCPP H5Object : public H5Location {
 	// Copy constructor: makes copy of an H5Object object.
 	H5Object(const H5Object& original);
 
+	// Gets the name of this HDF5 object, i.e., Group, DataSet, or
+	// DataType.
+	ssize_t getObjName(char *obj_name, size_t buf_size = 0) const;
+	ssize_t getObjName(H5std_string& obj_name, size_t len = 0) const;
+	H5std_string getObjName() const;
+
 	// Noop destructor.
 	virtual ~H5Object();
 
diff --git a/c++/test/Makefile.am b/c++/test/Makefile.am
index 6cef381..2717e9c 100644
--- a/c++/test/Makefile.am
+++ b/c++/test/Makefile.am
@@ -38,8 +38,8 @@ check_PROGRAMS=$(TEST_PROG)
 LDADD=$(LIBH5TEST) $(LIBH5CPP) $(LIBHDF5)
 
 testhdf5_SOURCES=testhdf5.cpp dsets.cpp tattr.cpp tcompound.cpp	\
-	tdspl.cpp tfile.cpp tfilter.cpp th5s.cpp tlinks.cpp trefer.cpp	\
-	ttypes.cpp tvlstr.cpp h5cpputil.cpp
+	tdspl.cpp tfile.cpp tfilter.cpp th5s.cpp tlinks.cpp tobject.cpp \
+	trefer.cpp ttypes.cpp tvlstr.cpp h5cpputil.cpp
 
 # Tell conclude.am that these are C++ tests.
 CXX_API=yes
diff --git a/c++/test/Makefile.in b/c++/test/Makefile.in
index 59cab8f..c1fd776 100644
--- a/c++/test/Makefile.in
+++ b/c++/test/Makefile.in
@@ -117,8 +117,8 @@ am__EXEEXT_1 = testhdf5$(EXEEXT)
 am_testhdf5_OBJECTS = testhdf5.$(OBJEXT) dsets.$(OBJEXT) \
 	tattr.$(OBJEXT) tcompound.$(OBJEXT) tdspl.$(OBJEXT) \
 	tfile.$(OBJEXT) tfilter.$(OBJEXT) th5s.$(OBJEXT) \
-	tlinks.$(OBJEXT) trefer.$(OBJEXT) ttypes.$(OBJEXT) \
-	tvlstr.$(OBJEXT) h5cpputil.$(OBJEXT)
+	tlinks.$(OBJEXT) tobject.$(OBJEXT) trefer.$(OBJEXT) \
+	ttypes.$(OBJEXT) tvlstr.$(OBJEXT) h5cpputil.$(OBJEXT)
 testhdf5_OBJECTS = $(am_testhdf5_OBJECTS)
 testhdf5_LDADD = $(LDADD)
 testhdf5_DEPENDENCIES = $(LIBH5TEST) $(LIBH5CPP) $(LIBHDF5)
@@ -681,8 +681,8 @@ TEST_PROG = testhdf5
 # The tests depend on the hdf5 library, test library, and the c++ library
 LDADD = $(LIBH5TEST) $(LIBH5CPP) $(LIBHDF5)
 testhdf5_SOURCES = testhdf5.cpp dsets.cpp tattr.cpp tcompound.cpp	\
-	tdspl.cpp tfile.cpp tfilter.cpp th5s.cpp tlinks.cpp trefer.cpp	\
-	ttypes.cpp tvlstr.cpp h5cpputil.cpp
+	tdspl.cpp tfile.cpp tfilter.cpp th5s.cpp tlinks.cpp tobject.cpp \
+	trefer.cpp ttypes.cpp tvlstr.cpp h5cpputil.cpp
 
 
 # Tell conclude.am that these are C++ tests.
@@ -774,6 +774,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tfilter.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/th5s.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tlinks.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tobject.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trefer.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ttypes.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tvlstr.Po@am__quote@
diff --git a/c++/test/dsets.cpp b/c++/test/dsets.cpp
index 72d7977..6824403 100644
--- a/c++/test/dsets.cpp
+++ b/c++/test/dsets.cpp
@@ -49,6 +49,7 @@
 
 const H5std_string	FILE1("dataset.h5");
 const H5std_string	DSET_DEFAULT_NAME("default");
+const H5std_string	DSET_DEFAULT_NAME_PATH("/default");
 const H5std_string	DSET_CHUNKED_NAME("chunked");
 const H5std_string	DSET_SIMPLE_IO_NAME("simple_io");
 const H5std_string	DSET_TCONV_NAME	("tconv");
@@ -96,6 +97,7 @@ test_create( H5File& file)
 	dataset = new DataSet (file.createDataSet
 		(DSET_DEFAULT_NAME, PredType::NATIVE_DOUBLE, space));
 
+
 	// Add a comment to the dataset
 	file.setComment (DSET_DEFAULT_NAME, "This is a dataset");
 
@@ -120,10 +122,15 @@ test_create( H5File& file)
 	// way to open an existing dataset for accessing.
 	dataset = new DataSet (file.openDataSet (DSET_DEFAULT_NAME));
 
+	// Get and verify the name of this dataset, using
+	// H5std_string getObjName()
+	H5std_string ds_name = dataset->getObjName();
+	verify_val(ds_name, DSET_DEFAULT_NAME_PATH, "DataSet::getObjName", __LINE__, __FILE__);
+
 	// Get and verify the comment from this dataset, using
 	// H5std_string getComment(const H5std_string& name, <buf_size=0, by default>)
 	H5std_string comment = file.getComment(DSET_DEFAULT_NAME);
-	verify_val(comment, "This is a dataset", "H5Location::getComment", __LINE__, __FILE__);
+	verify_val(comment, "This is a dataset", "DataSet::getComment", __LINE__, __FILE__);
 
 	// Close the dataset when accessing is completed
 	delete dataset;
@@ -1050,11 +1057,6 @@ void test_dset()
 
     try
     {
-	// Turn of the auto-printing when failure occurs so that we can
-	// handle the errors appropriately since sometime failures are
-	// caused deliberately and expected.
-	Exception::dontPrint();
-
 	// Use the file access template id to create a file access prop.
 	// list object to pass in H5File::H5File
 	FileAccPropList fapl(fapl_id);
@@ -1065,18 +1067,12 @@ void test_dset()
 	Group grp = file.createGroup( "emit diagnostics", 0);
 	grp.setComment("Causes diagnostic messages to be emitted");
 
-	nerrors += test_create(file)<0 	?1:0;
-	nerrors += test_simple_io(file)<0	?1:0;
-	nerrors += test_tconv(file)<0	?1:0;
-	nerrors += test_compression(file)<0	?1:0;
-	nerrors += test_multiopen (file)<0	?1:0;
-	nerrors += test_types(file)<0       ?1:0;
-
-	// Get part of the comment, random length using
-	// ssize_t getComment(const char* name, const size_t buf_size, char* comment)
-	char* comment = new char[11];
-	ssize_t comment_len = file.getComment("emit diagnostics", 11, comment);
-	verify_val((const char*)comment, "Causes dia", "H5Location::getComment", __LINE__, __FILE__);
+	nerrors += test_create(file) < 0 ? 1:0;
+	nerrors += test_simple_io(file) < 0 ? 1:0;
+	nerrors += test_tconv(file) < 0 ? 1:0;
+	nerrors += test_compression(file) < 0 ? 1:0;
+	nerrors += test_multiopen (file) < 0 ? 1:0;
+	nerrors += test_types(file) < 0 ? 1:0;
 
 	// Close group "emit diagnostics".
 	grp.close();
diff --git a/c++/test/h5cpputil.h b/c++/test/h5cpputil.h
index cc135bd..bea08d3 100644
--- a/c++/test/h5cpputil.h
+++ b/c++/test/h5cpputil.h
@@ -126,6 +126,7 @@ void test_file();
 void test_filters();
 void test_links();
 void test_h5s();
+void test_object();
 void test_reference();
 void test_types();
 void test_vlstrings();
@@ -140,6 +141,7 @@ void cleanup_file();
 void cleanup_filters();
 void cleanup_links();
 void cleanup_h5s();
+void cleanup_object();
 void cleanup_reference();
 void cleanup_types();
 void cleanup_vlstrings();
diff --git a/c++/test/tattr.cpp b/c++/test/tattr.cpp
index e2e347b..aa412d9 100644
--- a/c++/test/tattr.cpp
+++ b/c++/test/tattr.cpp
@@ -292,6 +292,7 @@ static void test_attr_getname()
 	HDmemset(fattr1_name, 0, buf_size+1);
 	ssize_t name_size = 0; // actual length of attribute name
 	name_size = fattr1.getName(fattr1_name, buf_size+1);
+	verify_val(name_size, FATTR1_NAME.length(), "Attribute::getName", __LINE__, __FILE__);
 	verify_val((const char*)fattr1_name, FATTR1_NAME, "Attribute::getName", __LINE__, __FILE__);
 	delete []fattr1_name;
 
@@ -302,6 +303,7 @@ static void test_attr_getname()
 	fattr1_name = new char[buf_size+1];
 	HDmemset(fattr1_name, 0, buf_size+1);
 	name_size = fattr1.getName(fattr1_name, buf_size+1);
+	verify_val(name_size, FATTR1_NAME.length(), "Attribute::getName", __LINE__, __FILE__);
 	verify_val((const char*)fattr1_name, (const char*)short_name, "Attribute::getName", __LINE__, __FILE__);
 	delete []fattr1_name;
 
@@ -1590,6 +1592,10 @@ extern "C"
 #endif
 void cleanup_attr()
 {
-    //HDremove(FILENAME.c_str());
+    HDremove(FILE_BASIC.c_str());
+    HDremove(FILE_COMPOUND.c_str());
+    HDremove(FILE_SCALAR.c_str());
+    HDremove(FILE_MULTI.c_str());
+    HDremove(FILE_DTYPE.c_str());
 }
 
diff --git a/c++/test/tcompound.cpp b/c++/test/tcompound.cpp
index 60d44b2..3258253 100644
--- a/c++/test/tcompound.cpp
+++ b/c++/test/tcompound.cpp
@@ -742,13 +742,12 @@ cerr << "test_compound_7 in catch" << endl;
  *
  *-------------------------------------------------------------------------
  */
-#define	COMPFILE	"tcompound_types.h5"
+const H5std_string COMPFILE("tcompound_types.h5");
 static void test_compound_set_size()
 {
     typedef struct {
 	int a, b, c[4], d, e;
     } src_typ_t;
-    src_typ_t	  *s_ptr;
 
     // Output message about test being performed
     SUBTEST("Setting Size on Compound Datatype");
@@ -867,4 +866,5 @@ extern "C"
 #endif
 void cleanup_compound()
 {
+    HDremove(COMPFILE.c_str());
 }   // cleanup_file
diff --git a/c++/test/tdspl.cpp b/c++/test/tdspl.cpp
index 5944fb1..5c1d953 100644
--- a/c++/test/tdspl.cpp
+++ b/c++/test/tdspl.cpp
@@ -50,7 +50,6 @@ static void test_transfplist()
     const char* simple = "(4/2) * ( (2 + 4)/(5 - 2.5))"; /* this equals 4.8 */
     /* inverses the utrans transform in init_test to get back original array */
     const char* utrans_inv = "(x/3)*4 - 100";
-    char *c_to_f_read=NULL, *simple_read=NULL, *utrans_inv_read=NULL;
 
     SUBTEST("DSetMemXferPropList::set/getDataTransform()");
     try {
@@ -75,7 +74,7 @@ static void test_transfplist()
 	// Find out the length of the transform expression, allocate the buffer
 	// for it, then read and verify the expression from the copied plist
 	ssize_t tran_len = dxpl_c_to_f_copy.getDataTransform(NULL);
-	c_to_f_read = (char *)HDmalloc(tran_len+1);
+	char *c_to_f_read = (char *)HDmalloc(tran_len+1);
 	HDmemset(c_to_f_read, 0, tran_len+1);
 	dxpl_c_to_f_copy.getDataTransform(c_to_f_read, tran_len+1);
 	verify_val((const char*)c_to_f_read, (const char*)c_to_f,
@@ -106,7 +105,7 @@ static void test_transfplist()
 	// Get and verify the expression with:
 	// ssize_t getDataTransform(char* exp, const size_t buf_size)
 	tran_len = dxpl_utrans_inv.getDataTransform(NULL, 0);
-	utrans_inv_read = (char *)HDmalloc(tran_len+1);
+	char *utrans_inv_read = (char *)HDmalloc(tran_len+1);
 	HDmemset(utrans_inv_read, 0, tran_len+1);
 	dxpl_utrans_inv.getDataTransform(utrans_inv_read, tran_len+1);
 	verify_val((const char*)utrans_inv_read, (const char*)utrans_inv,
diff --git a/c++/test/testhdf5.cpp b/c++/test/testhdf5.cpp
index 57210d0..19b4f0d 100644
--- a/c++/test/testhdf5.cpp
+++ b/c++/test/testhdf5.cpp
@@ -67,41 +67,54 @@
 int
 main(int argc, char *argv[])
 {
-    /* Initialize testing framework */
-    TestInit(argv[0], NULL, NULL);
-
-    // testing file creation and opening in tfile.cpp
-    AddTest("tfile", test_file, cleanup_file, "File I/O Operations", NULL);
-    // testing dataset functionalities in dset.cpp
-    AddTest("dsets", test_dset, cleanup_dsets, "Dataset I/O Operations", NULL);
-    // testing dataspace functionalities in th5s.cpp
-    AddTest("th5s",  test_h5s,  cleanup_h5s,  "Dataspaces", NULL);
-    // testing attribute functionalities in tattr.cpp
-    AddTest("tattr", test_attr, cleanup_attr,  "Attributes", NULL);
-    // testing reference functionalities in trefer.cpp
-    AddTest("trefer", test_reference, cleanup_reference,  "References", NULL);
-    // testing variable-length strings in tvlstr.cpp
-    AddTest("tvlstr", test_vlstrings, cleanup_vlstrings,  "Variable-Length Strings", NULL);
-    AddTest("ttypes", test_types, cleanup_types,  "Generic Data Types", NULL);
-    AddTest("tcompound", test_compound, cleanup_compound,  "Compound Data Types", NULL);
-    AddTest("tdspl", test_dsproplist, cleanup_dsproplist,  "Dataset Property List", NULL);
-    AddTest("tfilter", test_filters, cleanup_filters,  "Various Filters", NULL);
-    AddTest("tlinks", test_links, cleanup_links,  "Various Links", NULL);
+    try
+    {
+	// Turn of the auto-printing when failure occurs so that we can
+	// handle the errors appropriately since sometime failures are
+	// caused deliberately and expected.
+	Exception::dontPrint();
+	/* Initialize testing framework */
+	TestInit(argv[0], NULL, NULL);
+
+	// testing file creation and opening in tfile.cpp
+	AddTest("tfile", test_file, cleanup_file, "File I/O Operations", NULL);
+	// testing dataset functionalities in dset.cpp
+	AddTest("dsets", test_dset, cleanup_dsets, "Dataset I/O Operations", NULL);
+	// testing dataspace functionalities in th5s.cpp
+	AddTest("th5s",  test_h5s,  cleanup_h5s,  "Dataspaces", NULL);
+	// testing attribute functionalities in tattr.cpp
+	AddTest("tattr", test_attr, cleanup_attr,  "Attributes", NULL);
+	// testing object functionalities in tobject.cpp
+	AddTest("tobject", test_object, cleanup_object,  "Objects", NULL);
+	// testing reference functionalities in trefer.cpp
+	AddTest("trefer", test_reference, cleanup_reference,  "References", NULL);
+	// testing variable-length strings in tvlstr.cpp
+	AddTest("tvlstr", test_vlstrings, cleanup_vlstrings,  "Variable-Length Strings", NULL);
+	AddTest("ttypes", test_types, cleanup_types,  "Generic Data Types", NULL);
+	AddTest("tcompound", test_compound, cleanup_compound,  "Compound Data Types", NULL);
+	AddTest("tdspl", test_dsproplist, cleanup_dsproplist,  "Dataset Property List", NULL);
+	AddTest("tfilter", test_filters, cleanup_filters,  "Various Filters", NULL);
+	AddTest("tlinks", test_links, cleanup_links,  "Various Links", NULL);
 /* Comment out tests that are not done yet. - BMR, Feb 2001
-    AddTest("select", test_select, cleanup_select,  "Selections", NULL);
-    AddTest("time", test_time, cleanup_time,  "Time Datatypes", NULL);
-    AddTest("vltypes", test_vltypes, cleanup_vltypes,  "Variable-Length Datatypes", NULL);
-    AddTest("iterate", test_iterate, cleanup_iterate,  "Group & Attribute Iteration", NULL);
-    AddTest("array", test_array, cleanup_array,  "Array Datatypes", NULL);
-    AddTest("genprop", test_genprop, cleanup_genprop,  "Generic Properties", NULL);
-    AddTest("id", test_ids, NULL,  "User-Created Identifiers", NULL);
+	AddTest("select", test_select, cleanup_select,  "Selections", NULL);
+	AddTest("time", test_time, cleanup_time,  "Time Datatypes", NULL);
+	AddTest("vltypes", test_vltypes, cleanup_vltypes,  "Variable-Length Datatypes", NULL);
+	AddTest("iterate", test_iterate, cleanup_iterate,  "Group & Attribute Iteration", NULL);
+	AddTest("array", test_array, cleanup_array,  "Array Datatypes", NULL);
+	AddTest("genprop", test_genprop, cleanup_genprop,  "Generic Properties", NULL);
+	AddTest("id", test_ids, NULL,  "User-Created Identifiers", NULL);
 
 Comment out tests that are not done yet */
 
 /* Tentative - BMR 2007/1/12
-    AddTest("datatypes", test_dtypes, cleanup_dtypes,  "Data Types", NULL);
-    AddTest("enum", test_enum, cleanup_enum,  "Enum Data Types", NULL);
+	AddTest("enum", test_enum, cleanup_enum,  "Enum Data Types", NULL);
 */
+    }
+    catch (Exception E)
+    {
+        issue_fail_msg("Tests failed", __LINE__, __FILE__, E.getCDetailMsg());
+    }
+
     /* Display testing information */
     TestInfo(argv[0]);
 
diff --git a/c++/test/tfile.cpp b/c++/test/tfile.cpp
index 965065a..1f53e61 100644
--- a/c++/test/tfile.cpp
+++ b/c++/test/tfile.cpp
@@ -654,4 +654,5 @@ void cleanup_file()
     HDremove(FILE2.c_str());
     HDremove(FILE3.c_str());
     HDremove(FILE4.c_str());
+    HDremove(FILE5.c_str());
 }   // cleanup_file
diff --git a/c++/test/tfilter.cpp b/c++/test/tfilter.cpp
index 257e4be..854c7bb 100644
--- a/c++/test/tfilter.cpp
+++ b/c++/test/tfilter.cpp
@@ -165,7 +165,7 @@ static void test_null_filter()
 
 const H5std_string      DSET_SZIP_NAME("szipped dataset");
 
-void test_szip_filter(H5File& file1)
+static void test_szip_filter(H5File& file1)
 {
 #ifdef H5_HAVE_FILTER_SZIP
     int      points[DSET_DIM1][DSET_DIM2], check[DSET_DIM1][DSET_DIM2];
diff --git a/c++/test/tobject.cpp b/c++/test/tobject.cpp
new file mode 100644
index 0000000..e6ef69c
--- /dev/null
+++ b/c++/test/tobject.cpp
@@ -0,0 +1,269 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group.                                               *
+ * Copyright by the Board of Trustees of the University of Illinois.         *
+ * All rights reserved.                                                      *
+ *                                                                           *
+ * This file is part of HDF5.  The full HDF5 copyright notice, including     *
+ * terms governing use, modification, and redistribution, is contained in    *
+ * the files COPYING and Copyright.html.  COPYING can be found at the root   *
+ * of the source code distribution tree; Copyright.html can be found at the  *
+ * root level of an installed copy of the electronic HDF5 document set and   *
+ * is linked from the top-level documents page.  It can also be found at     *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html.  If you do not have          *
+ * access to either file, you may request a copy from help@hdfgroup.org.     *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*****************************************************************************
+   FILE
+   tobject.cpp - HDF5 C++ testing object related functionality
+
+ ***************************************************************************/
+
+#ifdef OLD_HEADER_FILENAME
+#include <iostream.h>
+#else
+#include <iostream>
+#endif
+#include <string>
+
+#ifndef H5_NO_NAMESPACE
+#ifndef H5_NO_STD
+    using std::cerr;
+    using std::endl;
+#endif  // H5_NO_STD
+#endif
+
+#include "H5Cpp.h"      // C++ API header file
+
+#ifndef H5_NO_NAMESPACE
+    using namespace H5;
+#endif
+
+#include "h5cpputil.h"  // C++ utilility header file
+
+const H5std_string	FILE_OBJECTS("tobjects.h5");
+const H5std_string	GROUP1("Top Group");
+const H5std_string	GROUP1_PATH("/Top Group");
+const H5std_string	GROUP1_1("Sub-Group 1.1");
+const H5std_string	GROUP1_1_PATH("/Top Group/Sub-Group 1.1");
+const H5std_string	GROUP1_2("Sub-Group 1.2");
+const H5std_string	GROUP1_2_PATH("/Top Group/Sub-Group 1.2");
+const H5std_string	DSET_DEFAULT_NAME("default");
+const H5std_string	DSET_IN_FILE("Dataset in File");
+const H5std_string	DSET_IN_FILE_PATH("/Dataset in File");
+const H5std_string	DSET_IN_GRP1("Dataset in Group 1");
+const H5std_string	DSET_IN_GRP1_PATH("/Top Group/Dataset in Group 1");
+const H5std_string	DSET_IN_GRP1_2("Dataset in Group 1.2");
+const H5std_string	DSET_IN_GRP1_2_PATH("/Top Group/Sub-Group 1.2/Dataset in Group 1.2");
+
+/*-------------------------------------------------------------------------
+ * Function:	test_get_objname
+ *
+ * Purpose:	Tests getting object name of groups and datasets.
+ *
+ * Return:	Success:	0
+ *		Failure:	-1
+ *
+ * Programmer:	Binh-Minh Ribler
+ *		Friday, March 4, 2014
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void test_get_objname()
+{
+    SUBTEST("H5Object::getObjName on Groups and Datasets");
+
+    try {
+	// Create file
+	H5File file(FILE_OBJECTS, H5F_ACC_TRUNC);
+
+	// Create a top group and 2 subgroups
+	Group grp1 = file.createGroup(GROUP1, 0);
+	Group grp1_1 = grp1.createGroup(GROUP1_1, 0);
+	Group grp1_2 = grp1.createGroup(GROUP1_2, 0);
+
+	// Get part of the group's name, random length using
+	// ssize_t getObjName(char* comment, size_t buf_size)
+
+	// Get the length of the group's name first
+	ssize_t name_len = grp1.getObjName(NULL);
+
+	// Random length is 4
+	if (name_len > 4)
+	{
+	    char* grp1_name = new char[5];
+	    name_len = grp1.getObjName(grp1_name, 5);
+	    verify_val((const char*)grp1_name, "/Top", "Group::getObjName", __LINE__, __FILE__);
+	    delete []grp1_name;
+	}
+
+	// Create a data space
+	hsize_t     dims[2];
+	dims[0] = 2;
+	dims[1] = 5;
+	DataSpace space (2, dims, NULL);
+
+	// Create a dataset in the file
+	DataSet dsinfile = file.createDataSet(DSET_IN_FILE,
+			 PredType::NATIVE_DOUBLE, space);
+
+	// Create a dataset in the group
+	DataSet dsingrp = grp1.createDataSet(DSET_IN_GRP1,
+			 PredType::NATIVE_INT, space);
+
+	// Get and verify the name of each dataset, using
+	// H5std_string getObjName() and
+	// ssize_t getObjName(H5std_string& obj_name, size_t len = 0)
+	H5std_string ds_name = dsinfile.getObjName();
+	verify_val(ds_name, DSET_IN_FILE_PATH, "DataSet::getObjName", __LINE__, __FILE__);
+
+	name_len = dsingrp.getObjName(ds_name); // default len
+	verify_val(ds_name, DSET_IN_GRP1_PATH, "DataSet::getObjName", __LINE__, __FILE__);
+
+	// Close dataset
+	dsingrp.close();
+
+	// Create a dataset in sub-group 1.2
+	dsingrp = grp1_2.createDataSet(DSET_IN_GRP1_2, PredType::NATIVE_INT, space);
+
+	// Get and verify the name of the dataset that belongs to subgroup
+	// 1.2, using H5std_string getObjName()
+	ds_name = dsingrp.getObjName();
+	verify_val(ds_name, DSET_IN_GRP1_2_PATH, "DataSet::getObjName", __LINE__, __FILE__);
+
+	// Close dataset
+	dsingrp.close();
+
+	// Reopen that same dataset then check the name again with another
+	// overload: ssize_t getObjName(H5std_string& obj_name, size_t len = 0)
+	dsingrp = grp1_2.openDataSet(DSET_IN_GRP1_2);
+	name_len = dsingrp.getObjName(ds_name);
+	verify_val(ds_name, DSET_IN_GRP1_2_PATH, "DataSet::getObjName", __LINE__, __FILE__);
+
+	// Everything will be closed as they go out of scope
+
+	PASSED();
+    }	// try block
+
+    // catch all other exceptions
+    catch (Exception E)
+    {
+	issue_fail_msg("test_get_objname", __LINE__, __FILE__);
+    }
+}   // test_get_objname
+
+/*-------------------------------------------------------------------------
+ * Function:	test_get_objname_ontypes
+ *
+ * Purpose:	Test getting object name from various committed types.
+ *
+ * Return:	Success:	0
+ *		Failure:	-1
+ *
+ * Programmer:  Binh-Minh Ribler
+ *		March 4, 2014
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void test_get_objname_ontypes()
+{
+    SUBTEST("H5Object::getObjName on Committed Datatypes");
+
+    try {
+	// Create a file with default prop lists
+	H5File file(FILE_OBJECTS, H5F_ACC_RDWR);
+
+	// Create a group
+	Group grp = file.createGroup ("typetests");
+
+	// Create a datatype and save it
+	DataType dtype(PredType::STD_B8LE);
+	dtype.commit(file, "STD_B8LE");
+
+	// Get and verify its name
+	H5std_string type_name = dtype.getObjName();
+	verify_val(type_name, "/STD_B8LE", "DataSet::getObjName", __LINE__, __FILE__);
+
+	// Test getting type's name from copied type
+	DataType copied_type;
+	copied_type.copy(dtype);
+	copied_type.commit(file, "copy of STD_B8LE");
+	type_name = copied_type.getObjName();
+	verify_val(type_name, "/copy of STD_B8LE", "DataSet::getObjName", __LINE__, __FILE__);
+
+	// Test copying an integer predefined type
+	IntType new_int_type(PredType::NATIVE_INT);
+
+	// Name this datatype
+	new_int_type.commit(grp, "IntType NATIVE_INT");
+	ssize_t name_len = new_int_type.getObjName(type_name); // default len
+	verify_val(type_name, "/typetests/IntType NATIVE_INT", "DataSet::getObjName", __LINE__, __FILE__);
+
+	// Close everything or they can be closed when objects go out of scope
+	dtype.close();
+	copied_type.close();
+	new_int_type.close();
+	grp.close();
+	file.close();
+
+	PASSED();
+    } // end top try block
+
+    catch (Exception E)
+    {
+	issue_fail_msg("test_get_objname_ontypes", __LINE__, __FILE__);
+    }
+}   // test_get_objname_ontypes
+
+/*-------------------------------------------------------------------------
+ * Function:	test_objects
+ *
+ * Purpose:	Tests HDF5 object related functionality
+ *
+ * Return:	Success: 0
+ *		Failure: -1
+ *
+ * Programmer:	Binh-Minh Ribler
+ *		Friday, Mar 4, 2014
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifdef __cplusplus
+extern "C"
+#endif
+void test_object()
+{
+    // Output message about test being performed
+    MESSAGE(5, ("Testing Object Functions\n"));
+
+    test_get_objname();    // Test get object name from groups/datasets
+    test_get_objname_ontypes();	// Test get object name from types
+
+}   // test_objects
+
+/*-------------------------------------------------------------------------
+ * Function:    cleanup_objects
+ *
+ * Purpose:     Cleanup temporary test files
+ *
+ * Return:      none
+ *
+ * Programmer:  (use C version)
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifdef __cplusplus
+extern "C"
+#endif
+void cleanup_object()
+{
+    HDremove(FILE_OBJECTS.c_str());
+} // cleanup_objects
diff --git a/c++/test/tvlstr.cpp b/c++/test/tvlstr.cpp
index 89f24f2..a2669db 100644
--- a/c++/test/tvlstr.cpp
+++ b/c++/test/tvlstr.cpp
@@ -50,10 +50,6 @@ const H5std_string FILENAME("tvlstr.h5");
 const int SPACE1_RANK = 1;
 const hsize_t SPACE1_DIM1 = 4;
 
-// Utility functions - not used now, later though.
-void *test_vlstr_alloc_custom(size_t size, void *info);
-void test_vlstr_free_custom(void *mem, void *info);
-
 /****************************************************************
 **
 **  test_vlstr_alloc_custom(): Test VL datatype custom memory
@@ -62,9 +58,9 @@ void test_vlstr_free_custom(void *mem, void *info);
 **	allocated.  It is passed into setVlenMemManager.
 **
 **  Note: exact copy from the C version.
-**
+**  (Not used now)
 ****************************************************************/
-void *test_vlstr_alloc_custom(size_t size, void *info)
+static void *test_vlstr_alloc_custom(size_t size, void *info)
 {
     void *ret_value=NULL;	// Pointer to return
     size_t *mem_used=(size_t *)info;  // Get the pointer to the memory used
@@ -94,9 +90,9 @@ void *test_vlstr_alloc_custom(size_t size, void *info)
 **	allocated.  It is passed into setVlenMemManager.
 **
 **  Note: exact copy from the C version.
-**
+**  (Not used now)
 ****************************************************************/
-void test_vlstr_free_custom(void *_mem, void *info)
+static void test_vlstr_free_custom(void *_mem, void *info)
 {
     unsigned char *mem;
     size_t *mem_used=(size_t *)info;  // Get the pointer to the memory used
-- 
cgit v0.12