From fabb06712b15f111c7ccce8c394ff6fc9bd2f997 Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Tue, 18 Jan 2005 21:51:12 -0500 Subject: [svn-r9838] Purpose: Bug fix Description: Correctly retire the H5E_LEN setting, now that the FORTRAN and C++ APIs have been corrected to not use it either. Solution: Pass in the string buffer length for FORTRAN In the C++ API, call H5Eget_msg() in a manner similar to the way H5Fget_name() is called. Platforms tested: Linux 2.4 (heping) w/FORTRAN & C++ Solaris 2.7 (arabica) w/FORTRAN & C++ --- c++/src/H5Exception.cpp | 48 ++++++++++++++++++++++++++++++++++++++++-------- fortran/src/H5Ef.c | 24 ++++++++++++++++-------- fortran/src/H5Eff.f90 | 11 +++++++---- fortran/src/H5f90proto.h | 4 ++-- src/H5Epublic.h | 3 --- 5 files changed, 65 insertions(+), 25 deletions(-) diff --git a/c++/src/H5Exception.cpp b/c++/src/H5Exception.cpp index d89f486..aef0d9c 100644 --- a/c++/src/H5Exception.cpp +++ b/c++/src/H5Exception.cpp @@ -66,10 +66,26 @@ Exception::Exception( const Exception& orig ) //-------------------------------------------------------------------------- string Exception::getMajorString( hid_t err_major ) const { - // calls the C API routine to get the major string - char msg[H5E_LEN]; - H5Eget_msg(err_major, NULL, msg, H5E_LEN); - string major_str(msg); + // Preliminary call to H5Eget_msg() to get the length of the message + ssize_t mesg_size = H5Eget_msg(err_major, NULL, NULL, 0); + + // If H5Eget_msg() returns a negative value, raise an exception, + if( mesg_size < 0 ) + throw IdComponentException("Exception::getMajorString", + "H5Eget_msg failed"); + + // Call H5Eget_msg again to get the actual message + char* mesg_C = new char[mesg_size+1]; // temporary C-string for C API + mesg_size = H5Eget_msg(err_major, NULL, mesg_C, mesg_size+1); + + // Check for failure again + if( mesg_size < 0 ) + throw IdComponentException("Exception::getMajorString", + "H5Eget_msg failed"); + + // Convert the C error description and return + string major_str(mesg_C); + delete mesg_C; return( major_str ); } @@ -86,10 +102,26 @@ string Exception::getMajorString( hid_t err_major ) const //-------------------------------------------------------------------------- string Exception::getMinorString( hid_t err_minor ) const { - // calls the C API routine to get the minor string - char msg[H5E_LEN]; - H5Eget_msg(err_minor, NULL, msg, H5E_LEN); - string minor_str(msg); + // Preliminary call to H5Eget_msg() to get the length of the message + ssize_t mesg_size = H5Eget_msg(err_minor, NULL, NULL, 0); + + // If H5Eget_msg() returns a negative value, raise an exception, + if( mesg_size < 0 ) + throw IdComponentException("Exception::getMinorString", + "H5Eget_msg failed"); + + // Call H5Eget_msg again to get the actual message + char* mesg_C = new char[mesg_size+1]; // temporary C-string for C API + mesg_size = H5Eget_msg(err_minor, NULL, mesg_C, mesg_size+1); + + // Check for failure again + if( mesg_size < 0 ) + throw IdComponentException("Exception::getMinorString", + "H5Eget_msg failed"); + + // Convert the C error description and return + string minor_str(mesg_C); + delete mesg_C; return( minor_str ); } diff --git a/fortran/src/H5Ef.c b/fortran/src/H5Ef.c index 3921ebf..6bd6d74 100644 --- a/fortran/src/H5Ef.c +++ b/fortran/src/H5Ef.c @@ -118,18 +118,22 @@ nh5eprint_c2() * Modifications: *---------------------------------------------------------------------------*/ int_f -nh5eget_major_c(int_f* error_no, _fcd name) +nh5eget_major_c(int_f* error_no, _fcd name, size_t_f* namelen) { int ret_val = -1; - char c_name[H5E_LEN]; + char *c_name; + size_t c_namelen; hid_t c_error_no; c_error_no = (hid_t)*error_no; + c_namelen = (size_t)*namelen; + if(c_namelen) c_name = (char*) HDmalloc(c_namelen + 1); + /* * Call H5Eget_major function. */ - H5Eget_msg(c_error_no, NULL, c_name, H5E_LEN); - HD5packFstring((char*)c_name, _fcdtocp(name), strlen(c_name)); + H5Eget_msg(c_error_no, NULL, c_name, c_namelen); + HD5packFstring((char*)c_name, _fcdtocp(name), c_namelen); if(!strcmp(c_name, "Invalid major error number")) return ret_val; ret_val = 0; @@ -148,18 +152,22 @@ nh5eget_major_c(int_f* error_no, _fcd name) * Modifications: *---------------------------------------------------------------------------*/ int_f -nh5eget_minor_c(int_f* error_no, _fcd name) +nh5eget_minor_c(int_f* error_no, _fcd name, size_t_f* namelen) { int ret_val = -1; - char c_name[H5E_LEN]; + char *c_name; + size_t c_namelen; hid_t c_error_no; c_error_no = (hid_t)*error_no; + c_namelen = (size_t)*namelen; + if(c_namelen) c_name = (char*) HDmalloc(c_namelen + 1); + /* * Call H5Eget_minor function. */ - H5Eget_msg(c_error_no, NULL, c_name, H5E_LEN); - HD5packFstring((char*)c_name, _fcdtocp(name), strlen(c_name)); + H5Eget_msg(c_error_no, NULL, c_name, c_namelen); + HD5packFstring((char*)c_name, _fcdtocp(name), c_namelen); if(!strcmp(c_name, "Invalid minor error number")) return ret_val; ret_val = 0; diff --git a/fortran/src/H5Eff.f90 b/fortran/src/H5Eff.f90 index 6e58bcf..2c64749 100644 --- a/fortran/src/H5Eff.f90 +++ b/fortran/src/H5Eff.f90 @@ -147,6 +147,7 @@ ! error_no - mojor error number ! Outputs: ! name - character string describing the error +! namelen - number of characters in the name buffer ! hdferr: - error code ! Success: 0 ! Failure: -1 @@ -162,7 +163,7 @@ ! Comment: !---------------------------------------------------------------------- - SUBROUTINE h5eget_major_f(error_no, name, hdferr) + SUBROUTINE h5eget_major_f(error_no, name, namelen, hdferr) ! !This definition is needed for Windows DLLs !DEC$if defined(BUILD_HDF5_DLL) @@ -172,24 +173,26 @@ INTEGER, INTENT(IN) :: error_no !Major error number CHARACTER(LEN=*), INTENT(OUT) :: name ! Character string describing ! the error. + INTEGER(SIZE_T), INTENT(IN) :: namelen !Anticipated number of characters in name. INTEGER, INTENT(OUT) :: hdferr ! Error code ! INTEGER, EXTERNAL :: h5eget_major_c ! MS FORTRAN needs explicit interface for C functions called here. ! INTERFACE - INTEGER FUNCTION h5eget_major_c(error_no, name) + INTEGER FUNCTION h5eget_major_c(error_no, name, namelen) USE H5GLOBAL !DEC$ IF DEFINED(HDF5F90_WINDOWS) !MS$ATTRIBUTES C,reference,alias:'_H5EGET_MAJOR_C'::h5eget_major_c !DEC$ ENDIF !DEC$ATTRIBUTES reference :: name INTEGER :: error_no - CHARACTER(LEN=*) :: name + CHARACTER(LEN=*) :: name + INTEGER(SIZE_T), INTENT(IN) :: namelen END FUNCTION h5eget_major_c END INTERFACE - hdferr = h5eget_major_c(error_no, name) + hdferr = h5eget_major_c(error_no, name, namelen) END SUBROUTINE h5eget_major_f !---------------------------------------------------------------------- diff --git a/fortran/src/H5f90proto.h b/fortran/src/H5f90proto.h index 437795c..7114ebf 100644 --- a/fortran/src/H5f90proto.h +++ b/fortran/src/H5f90proto.h @@ -948,8 +948,8 @@ H5_FCDLL int_f nh5iget_file_id_c(hid_t_f *obj_id, hid_t_f *file_id); H5_FCDLL int_f nh5eclear_c(void); H5_FCDLL int_f nh5eprint_c1(_fcd name, int_f* namelen); H5_FCDLL int_f nh5eprint_c2(void); -H5_FCDLL int_f nh5eget_major_c(int_f* error_no, _fcd name); -H5_FCDLL int_f nh5eget_minor_c(int_f* error_no, _fcd name); +H5_FCDLL int_f nh5eget_major_c(int_f* error_no, _fcd name, size_t_f* namelen); +H5_FCDLL int_f nh5eget_minor_c(int_f* error_no, _fcd name, size_t_f* namelen); H5_FCDLL int_f nh5eset_auto_c(int_f* printflag); /* diff --git a/src/H5Epublic.h b/src/H5Epublic.h index 2fc430f..1671967 100644 --- a/src/H5Epublic.h +++ b/src/H5Epublic.h @@ -27,9 +27,6 @@ /* Value for the default error stack */ #define H5E_DEFAULT 0 -/* Limit of error strings recorded */ -#define H5E_LEN 128 - /* Different kinds of error information */ typedef enum H5E_type_t { H5E_MAJOR, -- cgit v0.12