LCOV - code coverage report
Current view: top level - src - hsd_data_common.f90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 97.2 % 36 35
Test Date: 2026-02-15 21:36:29 Functions: 100.0 % 3 3

            Line data    Source code
       1              : !> Common utilities for hsd-data: format constants and detection.
       2              : module hsd_data_common
       3              :   implicit none(type, external)
       4              :   private
       5              : 
       6              :   !> Format identifier constants
       7              :   integer, parameter, public :: DATA_FMT_AUTO = 0  !< Detect from file extension
       8              :   integer, parameter, public :: DATA_FMT_HSD  = 1  !< HSD format
       9              :   integer, parameter, public :: DATA_FMT_XML  = 2  !< XML format
      10              :   integer, parameter, public :: DATA_FMT_JSON = 3  !< JSON format
      11              :   integer, parameter, public :: DATA_FMT_TOML = 4  !< TOML format
      12              :   integer, parameter, public :: DATA_FMT_HDF5 = 5  !< HDF5 format
      13              :   integer, parameter, public :: DATA_FMT_YAML = 6  !< YAML format
      14              : 
      15              :   public :: data_detect_format, data_format_available
      16              : 
      17              : contains
      18              : 
      19              :   !> Detect format from file extension.
      20              :   !>
      21              :   !> @param filename  Path to the file (only the extension is examined).
      22              :   !> @return DATA_FMT_* constant, or -1 if the extension is unrecognized.
      23           91 :   function data_detect_format(filename) result(fmt)
      24              :     character(len=*), intent(in) :: filename
      25              :     integer :: fmt
      26              : 
      27           91 :     character(len=:), allocatable :: ext
      28           91 :     integer :: dot_pos
      29              : 
      30           91 :     dot_pos = index(filename, ".", back=.true.)
      31           91 :     if (dot_pos == 0 .or. dot_pos == len(filename)) then
      32            2 :       fmt = -1
      33            2 :       return
      34              :     end if
      35              : 
      36           89 :     ext = to_lower(filename(dot_pos + 1:))
      37              : 
      38           36 :     select case (ext)
      39              :     case ("hsd")
      40           36 :       fmt = DATA_FMT_HSD
      41              :     case ("xml")
      42           12 :       fmt = DATA_FMT_XML
      43              :     case ("json")
      44           19 :       fmt = DATA_FMT_JSON
      45              :     case ("toml")
      46            4 :       fmt = DATA_FMT_TOML
      47              :     case ("h5", "hdf5")
      48            4 :       fmt = DATA_FMT_HDF5
      49              :     case ("yaml", "yml")
      50           12 :       fmt = DATA_FMT_YAML
      51              :     case default
      52           89 :       fmt = -1
      53              :     end select
      54              : 
      55           91 :   end function data_detect_format
      56              : 
      57              :   !> Check whether a format backend is available at runtime.
      58              :   !>
      59              :   !> TOML and HDF5 backends may be compiled out; this function lets callers
      60              :   !> verify availability before attempting to load or dump.
      61              :   !>
      62              :   !> @param fmt  Format constant (DATA_FMT_*).
      63              :   !> @return .true. if the backend is linked and ready.
      64            7 :   function data_format_available(fmt) result(available)
      65              :     integer, intent(in) :: fmt
      66              :     logical :: available
      67              : 
      68            8 :     select case (fmt)
      69              :     case (DATA_FMT_HSD)
      70            1 :       available = .true.
      71              :     case (DATA_FMT_XML)
      72            1 :       available = .true.
      73              :     case (DATA_FMT_JSON)
      74            1 :       available = .true.
      75              :     case (DATA_FMT_TOML)
      76              : #ifdef WITH_TOML
      77            1 :       available = .true.
      78              : #else
      79              :       available = .false.
      80              : #endif
      81              :     case (DATA_FMT_HDF5)
      82              : #ifdef WITH_HDF5
      83            2 :       available = .true.
      84              : #else
      85              :       available = .false.
      86              : #endif
      87              :     case (DATA_FMT_YAML)
      88            0 :       available = .true.
      89              :     case default
      90            1 :       available = .false.
      91              :     end select
      92              : 
      93           98 :   end function data_format_available
      94              : 
      95              :   !> Convert a string to lowercase (ASCII only).
      96           89 :   pure function to_lower(str) result(lower)
      97              :     character(len=*), intent(in) :: str
      98              :     character(len=:), allocatable :: lower
      99              : 
     100           89 :     integer :: ii, ic
     101              : 
     102           89 :     allocate(character(len=len(str)) :: lower)
     103          391 :     do ii = 1, len(str)
     104          302 :       ic = iachar(str(ii:ii))
     105          391 :       if (ic >= iachar("A") .and. ic <= iachar("Z")) then
     106           12 :         lower(ii:ii) = achar(ic + 32)
     107              :       else
     108          290 :         lower(ii:ii) = str(ii:ii)
     109              :       end if
     110              :     end do
     111              : 
     112           96 :   end function to_lower
     113              : 
     114              : end module hsd_data_common
        

Generated by: LCOV version 2.0-1