summaryrefslogtreecommitdiffstats
path: root/fortran/src/H5Eff.F90
blob: 9ea2807945184e0e0cb1e4cb54a7f21469da01f1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
!> @defgroup FH5E Fortran Error (H5E) Interface
!!
!! @see H5E, C-API
!!
!! @see @ref H5E_UG, User Guide
!!

!> @ingroup FH5E
!!
!! @brief This module contains Fortran interfaces for H5E functions.
!
! COPYRIGHT
! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
!   Copyright by The HDF Group.                                               *
!   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 COPYING file, which can be found at the root of the source code       *
!   distribution tree, or in https://www.hdfgroup.org/licenses.               *
!   If you do not have access to either file, you may request a copy from     *
!   help@hdfgroup.org.                                                        *
! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
!
! NOTES
!       _____ __  __ _____   ____  _____ _______       _   _ _______
!      |_   _|  \/  |  __ \ / __ \|  __ \__   __|/\   | \ | |__   __|
! ****   | | | \  / | |__) | |  | | |__) | | |  /  \  |  \| |  | |    ****
! ****   | | | |\/| |  ___/| |  | |  _  /  | | / /\ \ | . ` |  | |    ****
! ****  _| |_| |  | | |    | |__| | | \ \  | |/ ____ \| |\  |  | |    ****
!      |_____|_|  |_|_|     \____/|_|  \_\ |_/_/    \_\_| \_|  |_|
!
!  If you add a new H5E function to the module you must add the function name
!  to the Windows dll file 'hdf5_fortrandll.def.in' in the fortran/src directory.
!  This is needed for Windows based operating systems.
!
! MISSING: H5Eauto_is_v2, H5Eget_auto2

MODULE H5E

  USE H5GLOBAL
  USE H5fortkit
  IMPLICIT NONE

  INTEGER, PARAMETER :: PRINTON  = 1 !< Turn on automatic printing of errors
  INTEGER, PARAMETER :: PRINTOFF = 0 !< Turn off automatic printing of errors

!> @brief h5e_error_t derived type
  TYPE, BIND(C) :: h5e_error_t
     INTEGER(HID_T) :: cls_id  !< Class ID
     INTEGER(HID_T) :: maj_num !< Major error ID
     INTEGER(HID_T) :: min_num !< Minor error number
     INTEGER(C_INT) :: line      !< Line in file where error occurs
     TYPE(C_PTR)    :: func_name !< Function in which error occurred
     TYPE(C_PTR)    :: file_name !< File in which error occurred
     TYPE(C_PTR)    :: desc      !< Optional supplied description
  END TYPE h5e_error_t

  INTERFACE h5eprint_f
     MODULE PROCEDURE h5eprint1_f
     MODULE PROCEDURE h5eprint2_f
  END INTERFACE h5eprint_f

  INTERFACE
     INTEGER FUNCTION h5eprint_c(err_stack, name, namelen) BIND(C,NAME='h5eprint_c')
       IMPORT :: C_CHAR, HID_T, C_PTR
       IMPLICIT NONE
       INTEGER(HID_T)     :: err_stack
       CHARACTER(KIND=C_CHAR), DIMENSION(*) :: name
       TYPE(C_PTR), VALUE :: namelen
     END FUNCTION h5eprint_c
  END INTERFACE

CONTAINS

!>
!! \ingroup FH5E
!!
!! \brief Clears the error stack for the current thread.
!!
!! \param hdferr    \fortran_error
!! \param estack_id Error Stack id
!!
!! See C API: @ref H5Eclear2()
!!
  SUBROUTINE h5eclear_f(hdferr, estack_id)
    IMPLICIT NONE
    INTEGER, INTENT(OUT) :: hdferr
    INTEGER(HID_T), INTENT(IN), OPTIONAL :: estack_id
    INTEGER(HID_T) :: estack_id_default

    INTERFACE
       INTEGER(C_INT) FUNCTION H5Eclear(err_stack) BIND(C,NAME='H5Eclear2')
         IMPORT :: C_INT, HID_T
         IMPLICIT NONE
         INTEGER(HID_T), VALUE :: err_stack
       END FUNCTION H5Eclear
    END INTERFACE

    estack_id_default = H5E_DEFAULT_F
    IF(PRESENT(estack_id)) estack_id_default = estack_id

    hdferr = INT(H5Eclear(estack_id_default))
  END SUBROUTINE h5eclear_f

#ifdef H5_DOXYGEN
!>
!! \ingroup FH5E
!!
!! \brief Prints the error stack in a default manner.
!!
!! \param hdferr \fortran_error
!! \param name   Name of the file that contains print output
!!
!! \note If \p name is not specified, the output will be sent to
!!       the standard error (stderr).
!!
!! \attention Deprecated.
!!
!! See C API: @ref H5Eprint1()
!!
  SUBROUTINE h5eprint_f(hdferr, name)
    CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: name
    INTEGER, INTENT(OUT) :: hdferr
  END SUBROUTINE h5eprint_f

!! \ingroup FH5E
!!
!! \brief Prints the error stack in a default manner.
!!
!! \param err_stack Error stack identifier
!! \param hdferr    \fortran_error
!! \param name      Name of the file that contains print output
!!
!! \note If \p name is not specified, the output will be sent to
!!       the standard error (stderr).
!!
!! See C API: @ref H5Eprint2()
!!
  SUBROUTINE h5eprint_f(err_stack, hdferr, name)
    INTEGER(HID_T)  , INTENT(IN)  :: err_stack
    INTEGER         , INTENT(OUT) :: hdferr
    CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: name
  END SUBROUTINE h5eprint_f

#else

  SUBROUTINE h5eprint1_f(hdferr, name)
    CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: name
    INTEGER, INTENT(OUT) :: hdferr

    CALL h5eprint2_f(H5E_DEFAULT_F, hdferr, name)

  END SUBROUTINE h5eprint1_f

  SUBROUTINE h5eprint2_f(err_stack, hdferr, name)
    INTEGER(HID_T),   INTENT(IN) :: err_stack
    CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: name
    INTEGER, INTENT(OUT) :: hdferr

    INTEGER(SIZE_T), TARGET :: namelen
    TYPE(C_PTR)            :: c_namelen

    IF (PRESENT(name)) THEN
       namelen = LEN(NAME, SIZE_T)
       c_namelen = C_LOC(namelen)
       hdferr = h5eprint_c(err_stack, name, c_namelen)
    ELSE
       hdferr = h5eprint_c(err_stack, C_NULL_CHAR, C_NULL_PTR)
    ENDIF
  END SUBROUTINE h5eprint2_f

#endif

!>
!! \ingroup FH5E
!!
!! \brief Returns a character string describing an error specified by a major error number.
!!
!! \param error_no Major error number.
!! \param name     Character string describing the error.
!! \param namelen  Number of characters in the name buffer.
!! \param hdferr   \fortran_error
!!
!! \attention Deprecated: use H5Eget_msg_f() instead.
!!
!! See C API: @ref H5Eget_major()
!!
  SUBROUTINE h5eget_major_f(error_no, name, namelen, hdferr)
    INTEGER(HID_T)  , INTENT(IN)    :: error_no
    CHARACTER(LEN=*), INTENT(OUT)   :: name
    INTEGER(SIZE_T) , INTENT(INOUT) :: namelen
    INTEGER, INTENT(OUT) :: hdferr

    INTEGER :: msg_type
    INTEGER(SIZE_T) :: namelen2

    namelen2 = namelen

    CALL H5Eget_msg_f(error_no, msg_type, name, hdferr, namelen2)

  END SUBROUTINE h5eget_major_f
!>
!! \ingroup FH5E
!!
!! \brief Returns a character string describing an error specified by a minor error number.
!!
!! \param error_no Minor error number.
!! \param name     Character string describing the error.
!! \param hdferr   \fortran_error
!!
!! \attention Deprecated: use H5Eget_msg_f() instead.
!!
!! See C API: @ref H5Eget_minor()
!!
  SUBROUTINE h5eget_minor_f(error_no, name, hdferr)
    INTEGER(HID_T)  , INTENT(IN) :: error_no
    CHARACTER(LEN=*), INTENT(OUT) :: name
    INTEGER, INTENT(OUT) :: hdferr

    INTEGER :: msg_type

    CALL H5Eget_msg_f(error_no, msg_type, name, hdferr)

  END SUBROUTINE h5eget_minor_f
!>
!! \ingroup FH5E
!!
!! \brief Returns settings for automatic error stack traversal function and its data.
!!
!! \param printflag   Flag to turn automatic error printing on or off; possible values are:
!!                    \li printon (1)
!!                    \li printoff(0)
!! \param estack_id   Error stack identifier.
!! \param func        Function to be called upon an error condition.
!! \param client_data Data passed to the error function.
!! \param hdferr      \fortran_error
!!
!! See C API: @ref H5Eset_auto2()
!!
  SUBROUTINE h5eset_auto_f(printflag, hdferr, estack_id, func, client_data)
    USE, INTRINSIC :: ISO_C_BINDING, ONLY : C_PTR, C_FUNPTR
    INTEGER       , INTENT(IN)            :: printflag
    INTEGER       , INTENT(OUT)           :: hdferr
    INTEGER(HID_T), INTENT(IN) , OPTIONAL :: estack_id
    TYPE(C_FUNPTR), INTENT(IN) , OPTIONAL :: func
    TYPE(C_PTR)   , INTENT(IN) , OPTIONAL :: client_data
    INTEGER(HID_T) :: estack_id_default
    TYPE(C_FUNPTR) :: func_default
    TYPE(C_PTR)    :: client_data_default
    INTERFACE
       INTEGER FUNCTION h5eset_auto2_c(printflag, estack_id, func, client_data) &
            BIND(C, NAME='h5eset_auto2_c')
         IMPORT :: c_ptr, c_funptr
         IMPORT :: HID_T
         INTEGER :: printflag
         INTEGER(HID_T) :: estack_id
         TYPE(C_FUNPTR), VALUE :: func
         TYPE(C_PTR), VALUE :: client_data
       END FUNCTION h5eset_auto2_c
    END INTERFACE

    estack_id_default = -1
    func_default = C_NULL_FUNPTR
    client_data_default = C_NULL_PTR

    IF(PRESENT(estack_id)) estack_id_default = estack_id
    IF(PRESENT(func)) func_default = func
    IF(PRESENT(client_data)) client_data_default = client_data

    hdferr = h5eset_auto2_c(printflag, estack_id_default, func_default, client_data_default)
  END SUBROUTINE h5eset_auto_f
!>
!! \ingroup FH5E
!!
!! \brief Pushes a new error record onto an error stack.
!!
!! \param err_stack Error stack identifier. If the identifier is H5E_DEFAULT_F, the error
!!                  record will be pushed to the current stack.
!! \param cls_id Error class identifier
!! \param maj_id Major error identifier
!! \param min_id Minor error identifier
!! \param msg Error description string
!! \param hdferr \fortran_error
!! \param file Name of the file in which the error was detected
!! \param func Name of the function in which the error was detected
!! \param line Line number in the file where the error was detected
!! \param arg1 C style format control strings
!! \param arg2 C style format control strings
!! \param arg3 C style format control strings
!! \param arg4 C style format control strings
!! \param arg5 C style format control strings
!! \param arg6 C style format control strings
!! \param arg7 C style format control strings
!! \param arg8 C style format control strings
!! \param arg9 C style format control strings
!! \param arg10 C style format control strings
!! \param arg11 C style format control strings
!! \param arg12 C style format control strings
!! \param arg13 C style format control strings
!! \param arg14 C style format control strings
!! \param arg15 C style format control strings
!! \param arg16 C style format control strings
!! \param arg17 C style format control strings
!! \param arg18 C style format control strings
!! \param arg19 C style format control strings
!! \param arg20 C style format control strings
!!
!! \note \p arg[1-20] expects C-style format strings, similar to the
!!       system and C functions printf() and fprintf().
!!       Furthermore, special characters, such as ANSI escapes,
!!       will only be interpreted correctly if the Fortran equivalent
!!       is used. For example, to print \p msg "TEXT" in red and has
!!       a space after the text would be:
!!       <br /><br />
!!       \code
!!       (..., "%s TEXT %s"//C_NEW_LINE, hdferr, ..., arg1=ACHAR(27)//"[31m", arg2=ACHAR(27)//"[0m" )
!!       \endcode
!!       <br />Using "\n" instead of C_NEW_LINE will not be interpereted correctly, and similarly,
!!             using "\x1B" instead of ACHAR(27)
!!
!!
!! See C API: @ref H5Epush2()
!!
  SUBROUTINE h5epush_f(err_stack, cls_id, maj_id, min_id, msg, hdferr, &
       file, func, line, &
       arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, &
       arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20)
    IMPLICIT NONE
    INTEGER(HID_T), INTENT(IN) :: err_stack
    INTEGER(HID_T), INTENT(IN) :: cls_id
    INTEGER(HID_T), INTENT(IN) :: maj_id
    INTEGER(HID_T), INTENT(IN) :: min_id
    CHARACTER(LEN=*), INTENT(IN) :: msg
    INTEGER, INTENT(OUT) :: hdferr

    TYPE(C_PTR), OPTIONAL :: file
    TYPE(C_PTR), OPTIONAL :: func
    TYPE(C_PTR), OPTIONAL :: line
    CHARACTER(LEN=*), OPTIONAL, TARGET :: arg1, arg2, arg3, arg4, arg5, &
         arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, &
         arg16, arg17, arg18, arg19, arg20

    TYPE(C_PTR) :: file_def = C_NULL_PTR
    TYPE(C_PTR) :: func_def = C_NULL_PTR
    TYPE(C_PTR) :: line_def = C_NULL_PTR
    TYPE(C_PTR) :: arg1_def = C_NULL_PTR, arg2_def = C_NULL_PTR, &
         arg3_def = C_NULL_PTR, arg4_def = C_NULL_PTR, &
         arg5_def = C_NULL_PTR, arg6_def = C_NULL_PTR, &
         arg7_def = C_NULL_PTR, arg8_def = C_NULL_PTR, &
         arg9_def = C_NULL_PTR, arg10_def = C_NULL_PTR, &
         arg11_def = C_NULL_PTR, arg12_def = C_NULL_PTR, &
         arg13_def = C_NULL_PTR, arg14_def = C_NULL_PTR, &
         arg15_def = C_NULL_PTR, arg16_def = C_NULL_PTR, &
         arg17_def = C_NULL_PTR, arg18_def = C_NULL_PTR, &
         arg19_def = C_NULL_PTR, arg20_def = C_NULL_PTR

    INTERFACE
       INTEGER FUNCTION h5epush_c(err_stack, cls_id, maj_id, min_id, msg, msg_len, file, func, line, &
            arg1, arg2, arg3, arg4, arg5, &
            arg6, arg7, arg8, arg9, arg10, &
            arg11, arg12, arg13, arg14, arg15, &
            arg16, arg17, arg18, arg19, arg20) BIND(C, NAME='h5epush_c')

         IMPORT :: C_CHAR, C_INT, C_PTR
         IMPORT :: HID_T
         IMPLICIT NONE
         INTEGER(HID_T) :: err_stack
         INTEGER(HID_T) :: cls_id
         INTEGER(HID_T) :: maj_id
         INTEGER(HID_T) :: min_id
         CHARACTER(KIND=C_CHAR), DIMENSION(*) :: msg
         INTEGER :: msg_len

         TYPE(C_PTR), VALUE :: file
         TYPE(C_PTR), VALUE :: func
         TYPE(C_PTR), VALUE :: line
         TYPE(C_PTR), VALUE :: arg1, arg2, arg3, arg4, &
         arg5, arg6, arg7, arg8, &
         arg9, arg10, arg11, arg12, &
         arg13, arg14, arg15, arg16, &
         arg17, arg18, arg19, arg20

       END FUNCTION h5epush_c
    END INTERFACE

    IF (PRESENT(file)) file_def = file
    IF (PRESENT(func)) func_def = func
    IF (PRESENT(line)) line_def = line

    IF (PRESENT(arg1)) arg1_def = C_LOC(arg1(1:1))
    IF (PRESENT(arg2)) arg2_def = C_LOC(arg2(1:1))
    IF (PRESENT(arg3)) arg3_def = C_LOC(arg3(1:1))
    IF (PRESENT(arg4)) arg4_def = C_LOC(arg4(1:1))
    IF (PRESENT(arg5)) arg5_def = C_LOC(arg5(1:1))
    IF (PRESENT(arg6)) arg6_def = C_LOC(arg6(1:1))
    IF (PRESENT(arg7)) arg7_def = C_LOC(arg7(1:1))
    IF (PRESENT(arg8)) arg8_def = C_LOC(arg8(1:1))
    IF (PRESENT(arg9)) arg9_def = C_LOC(arg9(1:1))
    IF (PRESENT(arg10)) arg10_def = C_LOC(arg10(1:1))
    IF (PRESENT(arg11)) arg11_def = C_LOC(arg11(1:1))
    IF (PRESENT(arg12)) arg12_def = C_LOC(arg12(1:1))
    IF (PRESENT(arg13)) arg13_def = C_LOC(arg13(1:1))
    IF (PRESENT(arg14)) arg14_def = C_LOC(arg14(1:1))
    IF (PRESENT(arg15)) arg15_def = C_LOC(arg15(1:1))
    IF (PRESENT(arg16)) arg16_def = C_LOC(arg16(1:1))
    IF (PRESENT(arg17)) arg17_def = C_LOC(arg17(1:1))
    IF (PRESENT(arg18)) arg18_def = C_LOC(arg18(1:1))
    IF (PRESENT(arg19)) arg19_def = C_LOC(arg19(1:1))
    IF (PRESENT(arg20)) arg20_def = C_LOC(arg20(1:1))

    hdferr = h5epush_c(err_stack, cls_id, maj_id, min_id, msg, LEN(msg), &
         file_def, func_def, line_def, &
         arg1_def, arg2_def, arg3_def, arg4_def, arg5_def, &
         arg6_def, arg7_def, arg8_def, arg9_def, arg10_def, &
         arg11_def, arg12_def, arg13_def, arg14_def, arg15_def, &
         arg16_def, arg17_def, arg18_def, arg19_def, arg20_def)

  END SUBROUTINE h5epush_f
!>
!! \ingroup FH5E
!!
!! \brief Registers a client library or application program to the HDF5 error API.
!!
!! \param cls_name Name of the error class
!! \param lib_name Name of the client library or application to which the error class belongs
!! \param version  Version of the client library or application to which the error class belongs. It can be NULL.
!! \param class_id Class identifier
!! \param hdferr   \fortran_error
!!
!! See C API: @ref H5Eregister_class()
!!
  SUBROUTINE h5eregister_class_f(cls_name, lib_name, version, class_id, hdferr)
    IMPLICIT NONE
    CHARACTER(LEN=*), INTENT(IN)  :: cls_name
    CHARACTER(LEN=*), INTENT(IN)  :: lib_name
    CHARACTER(LEN=*), INTENT(IN)  :: version
    INTEGER(HID_T)  , INTENT(OUT) :: class_id
    INTEGER, INTENT(OUT) :: hdferr

    CHARACTER(LEN=LEN_TRIM(cls_name)+1,KIND=C_CHAR) :: c_cls_name
    CHARACTER(LEN=LEN_TRIM(lib_name)+1,KIND=C_CHAR) :: c_lib_name
    CHARACTER(LEN=LEN_TRIM(version)+1,KIND=C_CHAR) :: c_version
    INTERFACE
       INTEGER(HID_T) FUNCTION H5Eregister_class(cls_name, lib_name, version) &
            BIND(C,NAME='H5Eregister_class')
         IMPORT :: C_CHAR
         IMPORT :: HID_T
         IMPLICIT NONE
         CHARACTER(KIND=C_CHAR), DIMENSION(*) :: cls_name
         CHARACTER(KIND=C_CHAR), DIMENSION(*) :: lib_name
         CHARACTER(KIND=C_CHAR), DIMENSION(*) :: version

       END FUNCTION H5Eregister_class
    END INTERFACE

    c_cls_name = TRIM(cls_name)//C_NULL_CHAR
    c_lib_name = TRIM(lib_name)//C_NULL_CHAR
    c_version  = TRIM(version)//C_NULL_CHAR

    class_id = H5Eregister_class(c_cls_name, c_lib_name, c_version)

    hdferr = 0
    IF(class_id.LT.0) hdferr = -1

  END SUBROUTINE h5eregister_class_f
!>
!! \ingroup FH5E
!!
!! \brief Removes an error class.
!!
!! \param class_id Class identifier
!! \param hdferr   \fortran_error
!!
!! See C API: @ref H5Eunregister_class()
!!
  SUBROUTINE h5eunregister_class_f(class_id, hdferr)
    IMPLICIT NONE
    INTEGER(HID_T), INTENT(IN) :: class_id
    INTEGER, INTENT(OUT) :: hdferr

    INTERFACE
       INTEGER(C_INT) FUNCTION H5Eunregister_class(class_id) BIND(C, NAME='H5Eunregister_class')
         IMPORT :: HID_T, C_INT
         IMPLICIT NONE
         INTEGER(HID_T), INTENT(IN), VALUE :: class_id
       END FUNCTION H5Eunregister_class
    END INTERFACE

    hdferr = INT(H5Eunregister_class(class_id))

  END SUBROUTINE h5eunregister_class_f
!>
!! \ingroup FH5E
!!
!! \brief Adds a major or minor error message to an error class.
!!
!! \param class_id An error class identifier
!! \param msg_type The type of the error message
!! \param msg	   Error message
!! \param err_id   Error identifier
!! \param hdferr   \fortran_error
!!
!! See C API: @ref H5Ecreate_msg()
!!
  SUBROUTINE h5ecreate_msg_f(class_id, msg_type, msg, err_id, hdferr)
    IMPLICIT NONE

    INTEGER(HID_T)  , INTENT(IN)  :: class_id
    INTEGER         , INTENT(IN)  :: msg_type
    CHARACTER(LEN=*), INTENT(IN)  :: msg
    INTEGER(HID_T)  , INTENT(OUT) :: err_id
    INTEGER, INTENT(OUT) :: hdferr

    CHARACTER(LEN=LEN_TRIM(msg)+1,KIND=C_CHAR) :: c_msg

    INTERFACE
       INTEGER(HID_T) FUNCTION H5Ecreate_msg(class_id, msg_type, msg) &
            BIND(C,NAME='H5Ecreate_msg')
         IMPORT :: C_CHAR, C_INT
         IMPORT :: HID_T
         IMPLICIT NONE
         INTEGER(HID_T), VALUE  :: class_id
         INTEGER(C_INT), VALUE  :: msg_type
         CHARACTER(KIND=C_CHAR), DIMENSION(*) :: msg
       END FUNCTION H5Ecreate_msg
    END INTERFACE

    c_msg = TRIM(msg)//C_NULL_CHAR

    err_id = H5Ecreate_msg(class_id, INT(msg_type, C_INT), c_msg)

    hdferr = 0
    IF(err_id.LT.0) hdferr = -1

  END SUBROUTINE h5ecreate_msg_f
!>
!! \ingroup FH5E
!!
!! \brief Closes an error message.
!!
!! \param err_id An error message identifier
!! \param hdferr \fortran_error
!!
!! See C API: @ref H5Eclose_msg()
!!
  SUBROUTINE h5eclose_msg_f(err_id, hdferr)
    IMPLICIT NONE
    INTEGER(HID_T), INTENT(IN) :: err_id
    INTEGER, INTENT(OUT) :: hdferr

    INTERFACE
       INTEGER(C_INT) FUNCTION H5Eclose_msg(err_id) BIND(C, NAME='H5Eclose_msg')
         IMPORT :: HID_T, C_INT
         IMPLICIT NONE
         INTEGER(HID_T), VALUE :: err_id
       END FUNCTION H5Eclose_msg
    END INTERFACE

    hdferr = INT(H5Eclose_msg(err_id))

  END SUBROUTINE h5eclose_msg_f
!>
!! \ingroup FH5E
!!
!! \brief Retrieves an error message.
!!
!! \param msg_id   Error message identifier
!! \param msg_type The type of the error message. Valid values are H5E_MAJOR_F and H5E_MINOR_F.
!! \param msg	   Error message buffer
!! \param hdferr   \fortran_error
!! \param msg_size The length of error message to be returned by this function
!!
!! If \p msg_size is omitted, the API will copy up to the length of \p msg, and it
!! is the application's responsibility to provide a large enough buffer. If \p msg_size
!! is zero, the required buffer size will be returned, and \p msg is not accessed.
!! If \p msg_size is greater than zero, the function will copy up to the length
!! of \p msg_size info \p msg.
!!
!! See C API: @ref H5Eget_msg()
!!
  SUBROUTINE H5Eget_msg_f(msg_id, msg_type, msg, hdferr, msg_size)
    IMPLICIT NONE

    INTEGER(HID_T)  , INTENT(IN)    :: msg_id
    INTEGER         , INTENT(OUT)   :: msg_type
    CHARACTER(LEN=*)                :: msg
    INTEGER         , INTENT(OUT)   :: hdferr
    INTEGER(SIZE_T) , INTENT(INOUT), OPTIONAL :: msg_size

    CHARACTER(LEN=1,KIND=C_CHAR), DIMENSION(:), ALLOCATABLE, TARGET :: c_msg
    INTEGER(C_INT) :: c_msg_type
    TYPE(C_PTR) :: f_ptr
    INTEGER(SIZE_T) :: msg_cp_sz
    INTEGER(SIZE_T) :: c_msg_size

    INTERFACE
       INTEGER(SIZE_T) FUNCTION H5Eget_msg(msg_id, msg_type, msg, size) &
            BIND(C,NAME='H5Eget_msg')
         IMPORT :: C_CHAR, C_PTR, C_INT
         IMPORT :: HID_T, SIZE_T
         IMPLICIT NONE
         INTEGER(HID_T), VALUE  :: msg_id
         INTEGER(C_INT)         :: msg_type
         TYPE(C_PTR)    , VALUE :: msg
         INTEGER(SIZE_T), VALUE :: size
       END FUNCTION H5Eget_msg
    END INTERFACE

    hdferr = 0
    msg_cp_sz = 0
    IF(PRESENT(msg_size))THEN
       IF(msg_size .EQ. 0)THEN
          c_msg_size = H5Eget_msg(msg_id, c_msg_type, C_NULL_PTR, 0_SIZE_T)

          IF(PRESENT(msg_size)) msg_size = c_msg_size
          msg_type = INT(c_msg_type)

          IF(c_msg_size.LT.0) hdferr = -1
          RETURN
       ELSE
          msg_cp_sz = msg_size
       ENDIF
    ENDIF

    IF(msg_cp_sz.EQ.0) msg_cp_sz = LEN(msg)

    ALLOCATE(c_msg(1:msg_cp_sz+1), stat=hdferr)
    IF (hdferr .NE. 0) THEN
       hdferr = -1
       RETURN
    ENDIF
    f_ptr = C_LOC(c_msg(1)(1:1))
    c_msg_size = H5Eget_msg(msg_id, c_msg_type, f_ptr, msg_cp_sz+1)

    CALL HD5c2fstring(msg, c_msg, msg_cp_sz, msg_cp_sz+1_SIZE_T)

    DEALLOCATE(c_msg)

    IF(PRESENT(msg_size))THEN
       msg_size = c_msg_size
    ENDIF

    msg_type = INT(c_msg_type)

    IF(c_msg_size.LT.0) hdferr = -1

  END SUBROUTINE H5Eget_msg_f

!>
!! \ingroup FH5E
!!
!! \brief Retrieves the number of error messages in an error stack.
!!
!! \param error_stack_id An error message identifier
!! \param count          Number of error messages in \p err_id
!! \param hdferr         \fortran_error
!!
!! See C API: @ref H5Eget_num()
!!
  SUBROUTINE h5eget_num_f(error_stack_id, count, hdferr)
    IMPLICIT NONE
    INTEGER(HID_T) , INTENT(IN)  :: error_stack_id
    INTEGER(SIZE_T), INTENT(OUT) :: count
    INTEGER        , INTENT(OUT) :: hdferr

    INTERFACE
       INTEGER(SIZE_T) FUNCTION H5Eget_num(error_stack_id) BIND(C, NAME='H5Eget_num')
         IMPORT :: HID_T, SIZE_T
         IMPLICIT NONE
         INTEGER(HID_T), VALUE :: error_stack_id
       END FUNCTION H5Eget_num
    END INTERFACE

    count = H5Eget_num(error_stack_id)

    hdferr = 0
    IF(count.LT.0) hdferr = -1

  END SUBROUTINE h5eget_num_f

!>
!! \ingroup FH5E
!!
!! \brief Walks the specified error stack, calling the specified function.
!!
!! \param err_stack Error stack identifier
!! \param direction Direction in which the error stack is to be walked
!! \param op        Function to be called for each error encountered
!! \param op_data   Data to be passed to func
!! \param hdferr    \fortran_error
!!
!! See C API: @ref H5Ewalk2()
!!
  SUBROUTINE h5ewalk_f(err_stack, direction, op, op_data, hdferr)
    IMPLICIT NONE
    INTEGER(HID_T) , INTENT(IN)    :: err_stack
    INTEGER        , INTENT(IN)    :: direction
    TYPE(C_FUNPTR) , INTENT(IN)    :: op
    TYPE(C_PTR)    , INTENT(INOUT) :: op_data ! Declare INOUT to bypass gfortran 4.8.5 issue
    INTEGER        , INTENT(OUT)   :: hdferr

    INTERFACE
       INTEGER(C_INT) FUNCTION H5Ewalk(err_stack, direction, op, op_data) &
            BIND(C, NAME='H5Ewalk2')
         IMPORT :: HID_T, C_FUNPTR, C_PTR, C_INT
         IMPLICIT NONE
         INTEGER(HID_T), VALUE :: err_stack
         INTEGER(C_INT), VALUE :: direction
         TYPE(C_FUNPTR), VALUE :: op
         TYPE(C_PTR)   , VALUE :: op_data
       END FUNCTION H5Ewalk
    END INTERFACE

    hdferr = INT(H5Ewalk(err_stack, INT(direction, C_INT), op, op_data))

  END SUBROUTINE h5ewalk_f

!>
!! \ingroup FH5E
!!
!! \brief Retrieves an error message.
!!
!! \param class_id Error class identifier
!! \param name     Buffer for the error class name
!! \param hdferr   \fortran_error
!! \param size     The maximum number of characters of the class name to be returned by this function in \p name.
!!
!! If \p size is omitted, the API will copy up to the length of \p name, and it
!! is the application's responsibility to provide a large enough buffer. If \p size
!! is zero, the required buffer size will be returned, and \p name is not accessed.
!! If \p size is greater than zero, the function will copy up to the length
!! of \p size info \p name.
!!
!! See C API: @ref H5Eget_class_name()
!!
  SUBROUTINE H5Eget_class_name_f(class_id, name,  hdferr, size)
    IMPLICIT NONE

    INTEGER(HID_T)  , INTENT(IN)    :: class_id
    CHARACTER(LEN=*)                :: name
    INTEGER         , INTENT(OUT)   :: hdferr
    INTEGER(SIZE_T) , INTENT(INOUT), OPTIONAL :: size

    CHARACTER(LEN=1,KIND=C_CHAR), DIMENSION(:), ALLOCATABLE, TARGET :: c_name
    TYPE(C_PTR) :: f_ptr
    INTEGER(SIZE_T) :: name_cp_sz
    INTEGER(SIZE_T) :: c_size

    INTERFACE
       INTEGER(SIZE_T) FUNCTION H5Eget_class_name(class_id, name, size) &
            BIND(C,NAME='H5Eget_class_name')
         IMPORT :: C_PTR, C_CHAR
         IMPORT :: HID_T, SIZE_T
         IMPLICIT NONE
         INTEGER(HID_T) , VALUE :: class_id
         TYPE(C_PTR)    , VALUE :: name
         INTEGER(SIZE_T), VALUE :: size
       END FUNCTION H5Eget_class_name
    END INTERFACE

    hdferr = 0
    name_cp_sz = 0
    IF(PRESENT(size))THEN
       IF(size .EQ. 0)THEN
          c_size = H5Eget_class_name(class_id, C_NULL_PTR, 0_SIZE_T)

          IF(PRESENT(size)) size = c_size
          IF(c_size.LT.0) hdferr = -1
          RETURN
       ELSE
          name_cp_sz = size
       ENDIF
    ENDIF

    IF(name_cp_sz.EQ.0) name_cp_sz = LEN(name)

    ALLOCATE(c_name(1:name_cp_sz+1), stat=hdferr)
    IF (hdferr .NE. 0) THEN
       hdferr = -1
       RETURN
    ENDIF
    f_ptr = C_LOC(c_name)
    c_size = H5Eget_class_name(class_id, f_ptr, name_cp_sz+1_SIZE_T)

    CALL HD5c2fstring(name, c_name, name_cp_sz, name_cp_sz+1_SIZE_T)
    DEALLOCATE(c_name)

    IF(PRESENT(size))THEN
       size = c_size
    ENDIF

    IF(c_size.LT.0) hdferr = -1

  END SUBROUTINE H5Eget_class_name_f

!>
!! \ingroup FH5E
!!
!! \brief Appends one error stack to another, optionally closing the source stack.
!!
!! \param dst_stack_id       Error stack identifier
!! \param src_stack_id       Error stack identifier
!! \param close_source_stack Flag to indicate whether to close the source stack
!! \param hdferr             \fortran_error
!!
!! See C API: @ref H5Eappend_stack()
!!
  SUBROUTINE H5Eappend_stack_f(dst_stack_id, src_stack_id, close_source_stack, hdferr)
    IMPLICIT NONE
    INTEGER(HID_T), INTENT(IN)  :: dst_stack_id
    INTEGER(HID_T), INTENT(IN)  :: src_stack_id
    LOGICAL       , INTENT(IN)  :: close_source_stack
    INTEGER       , INTENT(OUT) :: hdferr

    INTERFACE
       INTEGER(C_INT) FUNCTION H5Eappend_stack(dst_stack_id, src_stack_id, close_source_stack) &
            BIND(C, NAME='H5Eappend_stack')
         IMPORT :: HID_T, C_BOOL, C_INT
         IMPLICIT NONE
         INTEGER(HID_T) , VALUE :: dst_stack_id
         INTEGER(HID_T) , VALUE :: src_stack_id
         LOGICAL(C_BOOL), VALUE :: close_source_stack
       END FUNCTION H5Eappend_stack
    END INTERFACE

    hdferr = INT(H5Eappend_stack(dst_stack_id, src_stack_id, LOGICAL(close_source_stack, C_BOOL)))

  END SUBROUTINE H5Eappend_stack_f

!>
!! \ingroup FH5E
!!
!! \brief Returns a copy of the current error stack.
!!
!! \param err_stack_id Error stack identifier
!! \param hdferr      \fortran_error
!!
!! See C API: @ref H5Eget_current_stack()
!!
  SUBROUTINE H5Eget_current_stack_f(err_stack_id, hdferr)
    IMPLICIT NONE
    INTEGER(HID_T), INTENT(OUT) :: err_stack_id
    INTEGER       , INTENT(OUT) :: hdferr

    INTERFACE
       INTEGER(HID_T) FUNCTION H5Eget_current_stack() BIND(C, NAME='H5Eget_current_stack')
         IMPORT :: HID_T
         IMPLICIT NONE
       END FUNCTION H5Eget_current_stack
    END INTERFACE

    err_stack_id = H5Eget_current_stack()

    hdferr = 0
    IF(err_stack_id.LT.0) hdferr = -1

  END SUBROUTINE H5Eget_current_stack_f

!>
!! \ingroup FH5E
!!
!! \brief Replaces the current error stack.
!!
!! \param err_stack_id Error stack identifier
!! \param hdferr       \fortran_error
!!
!! See C API: @ref H5Eset_current_stack()
!!
  SUBROUTINE H5Eset_current_stack_f(err_stack_id, hdferr)
    IMPLICIT NONE
    INTEGER(HID_T), INTENT(IN ) :: err_stack_id
    INTEGER       , INTENT(OUT) :: hdferr

    INTERFACE
       INTEGER(C_INT) FUNCTION H5Eset_current_stack(err_stack_id) BIND(C, NAME='H5Eset_current_stack')
         IMPORT :: C_INT, HID_T
         IMPLICIT NONE
         INTEGER(HID_T), VALUE :: err_stack_id
       END FUNCTION H5Eset_current_stack
    END INTERFACE

    hdferr = INT(H5Eset_current_stack(err_stack_id))

  END SUBROUTINE H5Eset_current_stack_f

!>
!! \ingroup FH5E
!!
!! \brief Closes an error stack handle.
!!
!! \param err_stack_id Error stack identifier
!! \param hdferr       \fortran_error
!!
!! See C API: @ref H5Eclose_stack()
!!
  SUBROUTINE H5Eclose_stack_f(err_stack_id, hdferr)
    IMPLICIT NONE
    INTEGER(HID_T), INTENT(IN ) :: err_stack_id
    INTEGER       , INTENT(OUT) :: hdferr

    INTERFACE
       INTEGER(C_INT) FUNCTION H5Eclose_stack(err_stack_id) BIND(C, NAME='H5Eclose_stack')
         IMPORT :: C_INT, HID_T
         IMPLICIT NONE
         INTEGER(HID_T), VALUE :: err_stack_id
       END FUNCTION H5Eclose_stack
    END INTERFACE

    hdferr = INT(H5Eclose_stack(err_stack_id))

  END SUBROUTINE H5Eclose_stack_f

!>
!! \ingroup FH5E
!!
!! \brief Creates a new, empty error stack.
!!
!! \param err_stack_id Error stack identifier
!! \param hdferr       \fortran_error
!!
!! See C API: @ref  H5Ecreate_stack()
!!
  SUBROUTINE H5Ecreate_stack_f(err_stack_id, hdferr)
    IMPLICIT NONE
    INTEGER(HID_T), INTENT(OUT) :: err_stack_id
    INTEGER       , INTENT(OUT) :: hdferr

    INTERFACE
       INTEGER(HID_T) FUNCTION H5Ecreate_stack() BIND(C, NAME='H5Ecreate_stack')
         IMPORT :: HID_T
         IMPLICIT NONE
       END FUNCTION H5Ecreate_stack
    END INTERFACE

    err_stack_id = H5Ecreate_stack()

    hdferr = 0
    IF(err_stack_id.LT.0) hdferr = -1

  END SUBROUTINE H5Ecreate_stack_f

!>
!! \ingroup FH5E
!!
!! \brief Deletes specified number of error messages from the error stack.
!!
!! \param err_stack_id Error stack identifier
!! \param count        The number of error messages to be deleted from the top of error stack
!! \param hdferr       \fortran_error
!!
!! See C API: @ref H5Epop()
!!
  SUBROUTINE H5Epop_f(err_stack_id, count, hdferr)
    IMPLICIT NONE
    INTEGER(HID_T) , INTENT(IN ) :: err_stack_id
    INTEGER(SIZE_T), INTENT(IN ) :: count
    INTEGER        , INTENT(OUT) :: hdferr

    INTERFACE
       INTEGER(C_INT) FUNCTION H5Epop(err_stack_id, count) BIND(C, NAME='H5Epop')
         IMPORT :: C_INT, HID_T, SIZE_T
         IMPLICIT NONE
         INTEGER(HID_T) , VALUE :: err_stack_id
         INTEGER(SIZE_T), VALUE :: count
       END FUNCTION H5Epop
    END INTERFACE

    hdferr = INT(H5Epop(err_stack_id, count))

  END SUBROUTINE H5Epop_f

END MODULE H5E