diff options
Diffstat (limited to 'fortran/test/tH5E_F03.F90')
-rw-r--r-- | fortran/test/tH5E_F03.F90 | 440 |
1 files changed, 361 insertions, 79 deletions
diff --git a/fortran/test/tH5E_F03.F90 b/fortran/test/tH5E_F03.F90 index c2bf74b..f5ed9fb 100644 --- a/fortran/test/tH5E_F03.F90 +++ b/fortran/test/tH5E_F03.F90 @@ -55,40 +55,116 @@ CONTAINS ! estack_id is always passed from C as: H5E_DEFAULT INTEGER(HID_T) :: estack_id + ! data that was registered with H5Eset_auto_f - INTEGER :: data_inout + ! INTEGER :: data_inout ! another option + ! or + TYPE(C_PTR), VALUE :: data_inout - PRINT*, " " - PRINT*, " Subtest: H5Eset_auto_f custom error message with callback, WITH DATA" - PRINT*, " -This message should be written to standard out- " - PRINT*, " Data Values Passed In =", data_inout - PRINT*, " " + INTEGER, POINTER :: iunit - data_inout = 10*data_inout + CALL C_F_POINTER(data_inout, iunit) - my_hdf5_error_handler = 1 ! this is not used by the C routine + ! iunit = data_inout - END FUNCTION my_hdf5_error_handler + WRITE(iunit,'(A)') "H5Eset_auto_f_msg" + WRITE(iunit,'(I0)') iunit - INTEGER FUNCTION my_hdf5_error_handler_nodata(estack_id, data_inout) bind(C) + iunit = 10*iunit - ! This error function handle works with only version 2 error stack - - IMPLICIT NONE + my_hdf5_error_handler = 1 ! this is not used by the C routine - ! estack_id is always passed from C as: H5E_DEFAULT - INTEGER(HID_T) :: estack_id - ! data that was registered with H5Eset_auto_f - TYPE(C_PTR) :: data_inout + END FUNCTION my_hdf5_error_handler - PRINT*, " " - PRINT*, " Subtest: H5Eset_auto_f custom error message with callback, NO DATA" - PRINT*, " -This message should be written to standard out- " - PRINT*, " " + !------------------------------------------------------------------------- + ! Function: custom_print_cb + ! + ! Purpose: Callback function to print error stack in customized way. + ! + !------------------------------------------------------------------------- + ! + INTEGER(C_INT) FUNCTION custom_print_cb(n, err_desc, op_data) BIND(C) - my_hdf5_error_handler_nodata = 1 ! this is not used by the C routine + IMPLICIT NONE - END FUNCTION my_hdf5_error_handler_nodata + INTEGER(SIZE_T), PARAMETER :: MSG_SIZE = 64 + + INTEGER(C_INT) :: n + TYPE(h5e_error_t) :: err_desc + TYPE(C_PTR) :: op_data + + CHARACTER(LEN=MSG_SIZE) :: maj + CHARACTER(LEN=MSG_SIZE) :: minn + CHARACTER(LEN=MSG_SIZE) :: cls + INTEGER(SIZE_T) :: size + INTEGER :: msg_type + + INTEGER :: error + + CALL H5Eget_class_name_f(err_desc%cls_id, cls, error) + IF(error .LT.0)THEN + custom_print_cb = -1 + RETURN + ENDIF + + IF(TRIM(cls).NE."Custom error class")THEN + custom_print_cb = -1 + RETURN + ENDIF + + size = 3 + CALL H5Eget_class_name_f(err_desc%cls_id, cls, error, size) + IF(error .LT.0)THEN + custom_print_cb = -1 + RETURN + ENDIF + IF(TRIM(cls).NE."Cus")THEN + custom_print_cb = -1 + RETURN + ENDIF + + size = 0 + CALL H5Eget_class_name_f(err_desc%cls_id, "", error, size) + IF(error .LT.0)THEN + custom_print_cb = -1 + RETURN + ENDIF + IF(size.NE.18)THEN + custom_print_cb = -1 + RETURN + ENDIF + + size = MSG_SIZE + CALL H5Eget_msg_f(err_desc%maj_num, msg_type, maj, error, size) + IF(error .LT.0)THEN + custom_print_cb = -1 + RETURN + ENDIF + + CALL h5eget_major_f(err_desc%maj_num, maj, size, error) + IF("MAJOR MSG".NE.TRIM(maj))THEN + custom_print_cb = -1 + RETURN + ENDIF + + IF(error .LT. 0)THEN + custom_print_cb = -1 + RETURN + ENDIF + + CALL h5eget_minor_f(err_desc%min_num, minn, error) + IF(error .LT. 0)THEN + custom_print_cb = -1 + RETURN + ENDIF + IF("MIN MSG".NE.TRIM(minn))THEN + custom_print_cb = -1 + RETURN + ENDIF + + custom_print_cb = 0 + + END FUNCTION custom_print_cb END MODULE test_my_hdf5_error_handler @@ -103,30 +179,24 @@ SUBROUTINE test_error(total_error) IMPLICIT NONE - INTEGER(hid_t), PARAMETER :: FAKE_ID = -1 INTEGER :: total_error INTEGER(hid_t) :: file - INTEGER(hid_t) :: dataset, space - INTEGER(hsize_t), DIMENSION(1:2) :: dims INTEGER :: error - INTEGER, DIMENSION(:), POINTER :: ptr_data INTEGER, TARGET :: my_hdf5_error_handler_data + INTEGER, TARGET :: iunit TYPE(C_PTR) :: f_ptr TYPE(C_FUNPTR) :: func + CHARACTER(LEN=180) :: chr180 + INTEGER :: idx - TYPE(C_PTR), TARGET :: f_ptr1 + LOGICAL :: status - INTEGER, DIMENSION(1:1) :: array_shape + ! set the error stack to the customized routine - my_hdf5_error_handler_data = 99 - CALL h5fcreate_f("terror.h5", H5F_ACC_TRUNC_F, file, error) - CALL check("h5fcreate_f", error, total_error) + iunit = 12 + OPEN(iunit, FILE="stderr.txt") - ! Create the data space - dims(1) = 10 - dims(2) = 20 - CALL H5Screate_simple_f(2, dims, space, error) - CALL check("h5screate_simple_f", error, total_error) + my_hdf5_error_handler_data = iunit ! ** SET THE CUSTOMIZED PRINTING OF ERROR STACK ** @@ -136,65 +206,277 @@ SUBROUTINE test_error(total_error) ! set the data sent to the customized routine f_ptr = c_loc(my_hdf5_error_handler_data) - ! turn on automatic printing, and use a custom error routine with input data CALL H5Eset_auto_f(1, error, H5E_DEFAULT_F, func, f_ptr) + CALL check("H5Eset_auto_f", error, total_error) - ! Create the erring dataset - CALL h5dcreate_f(FAKE_ID,"a_dataset",H5T_NATIVE_INTEGER, space, dataset, error) - CALL verify("h5dcreate_f", error, -1, total_error) + CALL h5fopen_f("DOESNOTEXIST", H5F_ACC_RDONLY_F, file, error) + CALL VERIFY("h5fopen_f", error, -1, total_error) -!!$ CALL verify("H5Eset_auto_f",my_hdf5_error_handler_data(1),10, total_error) -!!$ CALL verify("H5Eset_auto_f",my_hdf5_error_handler_data(2),20, total_error) + CLOSE(iunit) -!!$ ! Test enabling and disabling default printing -!!$ -!!$ CALL H5Eget_auto_f(H5E_DEFAULT_F, func1, f_ptr1, error) -!!$ CALL verify("H5Eget_auto_f", error, 0, total_error) + OPEN(iunit, FILE="stderr.txt") - ! PRINT*,c_associated(f_ptr1) + READ(iunit,'(A)') chr180 + idx = INDEX(string=chr180,substring="H5Eset_auto_f_msg") + IF(idx.EQ.0) CALL check("H5Eset_auto_f", -1, total_error) + READ(iunit, *) idx + CALL VERIFY("H5Eset_auto_f", idx, iunit, total_error) + CALL VERIFY("H5Eset_auto_f", my_hdf5_error_handler_data, 10*iunit, total_error) - ALLOCATE(ptr_data(1:2)) - ptr_data = 0 - array_shape(1) = 2 - CALL C_F_POINTER(f_ptr1, ptr_data, array_shape) + CLOSE(iunit, STATUS='delete') - ! ptr_data => f_ptr1(1) + CALL H5Eset_auto_f(0, error) + CALL check("H5Eset_auto_f", error, total_error) - ! PRINT*,ptr_data(1) + CALL h5fopen_f("DOESNOTEXIST", H5F_ACC_RDONLY_F, file, error) + CALL VERIFY("h5fopen_f", error, -1, total_error) -!!$ if(old_data != NULL) -!!$ TEST_ERROR; -!!$#ifdef H5_USE_16_API -!!$ if (old_func != (H5E_auto_t)H5Eprint) -!!$ TEST_ERROR; -!!$#else H5_USE_16_API -!!$ if (old_func != (H5E_auto2_t)H5Eprint2) -!!$ TEST_ERROR; -!!$#endif H5_USE_16_API + INQUIRE(file="H5Etest.txt", EXIST=status) + IF(status)THEN + CALL VERIFY("H5Eset_auto_f", error, -1, total_error) + ENDIF +END SUBROUTINE test_error - ! set the customized error handling routine - func = c_funloc(my_hdf5_error_handler_nodata) - ! set the data sent to the customized routine as null - f_ptr = C_NULL_PTR - ! turn on automatic printing, and use a custom error routine with no input data - CALL H5Eset_auto_f(1, error, H5E_DEFAULT_F, func, f_ptr) +SUBROUTINE test_error_stack(total_error) + + IMPLICIT NONE + + INTEGER :: total_error + INTEGER :: error + INTEGER(HID_T) :: cls_id, major, minor, estack_id, estack_id1, estack_id2 + CHARACTER(LEN=18), TARGET :: file + CHARACTER(LEN=18), TARGET :: func + INTEGER , TARGET :: line + TYPE(C_PTR) :: ptr1, ptr2, ptr3, ptr4 + + INTEGER :: msg_type + CHARACTER(LEN=9) :: maj_mesg = "MAJOR MSG" + CHARACTER(LEN=7) :: min_mesg = "MIN MSG" + !file status + LOGICAL :: status + CHARACTER(LEN=180) :: chr180 + INTEGER :: idx + INTEGER(SIZE_T) :: count + CHARACTER(LEN=64), TARGET :: stderr + TYPE(C_FUNPTR) :: func_ptr + +#ifdef H5_FORTRAN_HAVE_CHAR_ALLOC + CHARACTER(:), ALLOCATABLE :: msg_alloc +#endif + + CHARACTER(LEN=9) :: chr9 + INTEGER(SIZE_T) :: msg_size + + CALL h5eregister_class_f("Custom error class", "H5E_F03", "0.1", cls_id, error) + CALL check("H5Eregister_class_f", error, total_error) + + CALL H5Ecreate_msg_f(cls_id, H5E_MAJOR_F, maj_mesg, major, error) + CALL check("H5Ecreate_msg_f", error, total_error) + CALL H5Ecreate_msg_f(cls_id, H5E_MINOR_F, min_mesg, minor, error) + CALL check("H5Ecreate_msg_f", error, total_error) + + file = "FILE"//C_NULL_CHAR + func = "FUNC"//C_NULL_CHAR + line = 99 + + ptr1 = C_LOC(file) + ptr2 = C_LOC(func) + ptr3 = C_LOC(line) + + CALL h5ecreate_stack_f(estack_id, error) + CALL check("h5ecreate_stack_f", error, total_error) + + ! push a custom error message onto the stack + CALL H5Epush_f(estack_id, cls_id, major, minor, "%s ERROR TEXT %s"//C_NEW_LINE, error, & + ptr1, ptr2, ptr3, & + arg1=ACHAR(27)//"[31m", arg2=ACHAR(27)//"[0m" ) + CALL check("H5Epush_f", error, total_error) + + CALL h5eget_num_f(estack_id, count, error) + CALL check("h5eget_num_f", error, total_error) + CALL VERIFY("h5eget_num_f", count, 1_SIZE_T, total_error) + + msg_size = 0 + CALL H5Eget_msg_f(major, msg_type, chr9, error, msg_size) + CALL check("H5Eget_msg_f", error, total_error) + CALL VERIFY("H5Eget_msg_f", msg_type, H5E_MAJOR_F, total_error) + CALL VERIFY("H5Eget_msg_f", msg_size, 9_SIZE_T, total_error) + + ! Check when a shorter buffer length is passed as the msg_size + msg_size = 3 + CALL H5Eget_msg_f(major, msg_type, chr9, error, msg_size) + CALL check("H5Eget_msg_f", error, total_error) + CALL VERIFY("H5Eget_msg_f", msg_type, H5E_MAJOR_F, total_error) + CALL VERIFY("H5Eget_msg_f", msg_size, 9_SIZE_T, total_error) + CALL VERIFY("H5Eget_msg_f", TRIM(chr9), maj_mesg(1:3), total_error) + + ! Check when a exact size buffer length is passed as the msg_size + msg_size = 9 + CALL H5Eget_msg_f(major, msg_type, chr9, error, msg_size) + CALL check("H5Eget_msg_f", error, total_error) + CALL VERIFY("H5Eget_msg_f", msg_type, H5E_MAJOR_F, total_error) + CALL VERIFY("H5Eget_msg_f", msg_size, 9_SIZE_T, total_error) + CALL VERIFY("H5Eget_msg_f", TRIM(chr9), maj_mesg(1:9), total_error) + + msg_size = 0 + CALL H5Eget_msg_f(minor, msg_type, chr9, error, msg_size) + CALL check("H5Eget_msg_f", error, total_error) + CALL VERIFY("H5Eget_msg_f", msg_type, H5E_MINOR_F, total_error) + CALL VERIFY("H5Eget_msg_f", msg_size, 7_SIZE_T, total_error) + + ! Check when a shorter buffer length is passed as the msg_size + msg_size = 3 + CALL H5Eget_msg_f(minor, msg_type, chr9, error, msg_size) + CALL check("H5Eget_msg_f", error, total_error) + CALL VERIFY("H5Eget_msg_f", msg_type, H5E_MINOR_F, total_error) + CALL VERIFY("H5Eget_msg_f", msg_size, 7_SIZE_T, total_error) + CALL VERIFY("H5Eget_msg_f", TRIM(chr9), min_mesg(1:3), total_error) + + ! Check when a larger buffer length is passed as the msg_size + msg_size = 9 + CALL H5Eget_msg_f(minor, msg_type, chr9, error, msg_size) + CALL check("H5Eget_msg_f", error, total_error) + CALL VERIFY("H5Eget_msg_f", msg_type, H5E_MINOR_F, total_error) + CALL VERIFY("H5Eget_msg_f", msg_size, 7_SIZE_T, total_error) + CALL VERIFY("H5Eget_msg_f", TRIM(chr9), min_mesg(1:7), total_error) + + ! Check with an allocatable character of the exact size +#ifdef H5_FORTRAN_HAVE_CHAR_ALLOC + msg_size = 0 + CALL H5Eget_msg_f(minor, msg_type, "", error, msg_size) + CALL check("H5Eget_msg_f", error, total_error) + CALL VERIFY("H5Eget_msg_f", msg_type, H5E_MINOR_F, total_error) + CALL VERIFY("H5Eget_msg_f", msg_size, 7_SIZE_T, total_error) + + ALLOCATE(CHARACTER(LEN=msg_size) :: msg_alloc) + CALL H5Eget_msg_f(minor, msg_type, msg_alloc, error) + CALL check("H5Eget_msg_f", error, total_error) + CALL VERIFY("H5Eget_msg_f", msg_type, H5E_MINOR_F, total_error) + CALL VERIFY("H5Eget_msg_f", msg_alloc, min_mesg, total_error) +#endif + + CALL h5eprint_f(H5E_DEFAULT_F, error) + CALL check("h5eprint_f", error, total_error) + CALL h5eprint_f(error) + CALL check("h5eprint_f", error, total_error) + + INQUIRE(file="H5Etest.txt", EXIST=status) + IF(status)THEN + OPEN(UNIT=12, FILE="H5Etest.txt", status='old') + CLOSE(12, STATUS='delete') + ENDIF + + CALL h5eprint_f(estack_id, error, "H5Etest.txt") + CALL check("h5eprint_f", error, total_error) + + INQUIRE(file="H5Etest.txt", EXIST=status) + IF(.NOT.status)THEN + CALL check("h5eprint_f", -1, total_error) + ELSE + OPEN(UNIT=12, FILE="H5Etest.txt", status='old') + + READ(12,'(A)') chr180 + idx = INDEX(string=chr180,substring="Custom error class") + IF(idx.EQ.0) CALL check("h5eprint_f1", -1, total_error) + idx = INDEX(string=chr180,substring="H5E_F03") + IF(idx.EQ.0) CALL check("h5eprint_f2", -1, total_error) + idx = INDEX(string=chr180,substring="0.1") + IF(idx.EQ.0) CALL check("h5eprint_f3", -1, total_error) + + READ(12,'(A)') chr180 + idx = INDEX(string=chr180,substring="FILE") + IF(idx.EQ.0) CALL check("h5eprint_f4", -1, total_error) + idx = INDEX(string=chr180,substring="99") + IF(idx.EQ.0) CALL check("h5eprint_f5", -1, total_error) + idx = INDEX(string=chr180,substring="FUNC") + IF(idx.EQ.0) CALL check("h5eprint_f6", -1, total_error) + idx = INDEX(string=chr180,substring="ERROR TEXT") + IF(idx.EQ.0) CALL check("h5eprint_f7", -1, total_error) + + READ(12,'()') + + READ(12,"(A)") chr180 + idx = INDEX(string=chr180,substring=maj_mesg) + IF(idx.EQ.0) CALL check("h5eprint_f", -1, total_error) + + READ(12,"(A)") chr180 + idx = INDEX(string=chr180,substring=min_mesg) + IF(idx.EQ.0) CALL check("h5eprint_f", -1, total_error) + + CLOSE(12, STATUS='delete') + ENDIF + + stderr = "** Print error stack in customized way **"//C_NULL_CHAR + ptr4 = C_LOC(stderr(1:1)) + func_ptr = C_FUNLOC(custom_print_cb) + + CALL h5ewalk_f(estack_id, H5E_WALK_UPWARD_F, func_ptr, ptr4, error) + CALL check("h5ewalk_f", error, total_error) + + CALL h5eget_num_f(estack_id, count, error) + CALL check("h5eget_num_f", error, total_error) + CALL VERIFY("h5eget_num_f", count, 1_SIZE_T, total_error) + + CALL H5Ecreate_stack_f(estack_id2, error) + CALL check("H5Ecreate_stack_f", error, total_error) + + CALL H5Eappend_stack_f(estack_id2, estack_id, .FALSE., error) + CALL check("H5Eappend_stack_f", error, total_error) + + CALL h5eget_num_f(estack_id2, count, error) + CALL check("h5eget_num_f", error, total_error) + CALL VERIFY("h5eget_num_f", count, 1_SIZE_T, total_error) + + ! Copy error stack, which clears the original + CALL H5Eget_current_stack_f(estack_id1, error) + CALL check("H5Eget_current_stack_f", error, total_error) + + CALL h5eget_num_f(estack_id1, count, error) + CALL check("h5eget_num_f", error, total_error) + CALL VERIFY("h5eget_num_f", count, 0_SIZE_T, total_error) + + CALL H5Eclose_stack_f(estack_id2, error) + CALL check(" H5Eclose_stack_f", error, total_error) + + CALL H5Eclose_stack_f(estack_id, error) + CALL check("H5Eclose_stack_f", error, total_error) + + CALL H5Eclose_stack_f(estack_id1, error) + CALL check("H5Eclose_stack_f", error, total_error) + + CALL h5ecreate_stack_f(estack_id1, error) + CALL check("h5ecreate_stack_f", error, total_error) - CALL h5dcreate_f(FAKE_ID,"a_dataset",H5T_NATIVE_INTEGER, space, dataset, error) - CALL verify("h5dcreate_f", error, -1, total_error) + ! push a custom error message onto the stack + CALL H5Epush_f(estack_id1, cls_id, major, minor, "%s ERROR TEXT %s"//C_NEW_LINE, error, & + ptr1, ptr2, ptr3, & + arg1=ACHAR(27)//"[31m", arg2=ACHAR(27)//"[0m" ) + CALL check("H5Epush_f", error, total_error) + CALL H5Eset_current_stack_f(estack_id1, error) ! API will also close estack_id1 + CALL check("H5Eset_current_stack_f", error, total_error) - ! turn on automatic printing with h5eprint_f which prints an error stack in the default manner. + CALL h5eget_num_f(H5E_DEFAULT_F, count, error) + CALL check("h5eget_num_f", error, total_error) + CALL VERIFY("h5eget_num_f", count, 1_SIZE_T, total_error) - ! func = c_funloc(h5eprint_f) - ! CALL H5Eset_auto_f(0, error, H5E_DEFAULT_F, func, C_NULL_PTR) + CALL h5epop_f(H5E_DEFAULT_F, 1_size_t, total_error) + CALL check("h5epop_f", error, total_error) - CALL H5Eset_auto_f(0, error) - CALL h5dcreate_f(FAKE_ID,"a_dataset",H5T_NATIVE_INTEGER, space, dataset, error) + CALL h5eget_num_f(H5E_DEFAULT_F, count, error) + CALL check("h5eget_num_f", error, total_error) + CALL VERIFY("h5eget_num_f", count, 0_SIZE_T, total_error) - CALL H5Eset_auto_f(1, error) - CALL h5dcreate_f(FAKE_ID,"a_dataset",H5T_NATIVE_INTEGER, space, dataset, error) + CALL H5Eclose_msg_f(major, error) + CALL check("H5Eclose_msg_f", error, total_error) -END SUBROUTINE test_error + CALL H5Eclose_msg_f(minor, error) + CALL check("H5Eclose_msg_f", error, total_error) + + CALL h5eunregister_class_f(cls_id, error) + CALL check("H5Eunregister_class_f", error, total_error) + +END SUBROUTINE test_error_stack END MODULE TH5E_F03 |