2020-04-22 16:22:47 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-05-08 02:40:27 +05:30
|
|
|
!> @author Sharan Roongta, Max-Planck-Institut für Eisenforschung GmbH
|
|
|
|
!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH
|
|
|
|
!> @brief Data types to create a scalar, a list, and a dictionary/hash
|
2020-04-22 16:22:47 +05:30
|
|
|
!> @details module describes the various functions to store and get the yaml data.
|
2020-05-08 02:40:27 +05:30
|
|
|
!! A node is the base class for scalar, list and dictionary, list items and dictionary entries point
|
|
|
|
!! to a node.
|
2020-04-22 16:22:47 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
|
2020-04-28 13:59:13 +05:30
|
|
|
module YAML_types
|
2020-04-22 16:22:47 +05:30
|
|
|
use IO
|
|
|
|
use prec
|
|
|
|
|
|
|
|
implicit none
|
|
|
|
private
|
|
|
|
|
2020-05-22 00:22:15 +05:30
|
|
|
type, abstract, public :: tNode
|
2020-04-22 16:22:47 +05:30
|
|
|
integer :: length = 0
|
|
|
|
contains
|
|
|
|
procedure(asFormattedString), deferred :: asFormattedString
|
|
|
|
procedure :: &
|
|
|
|
asScalar => tNode_asScalar
|
2020-06-16 19:27:16 +05:30
|
|
|
procedure :: &
|
|
|
|
isScalar => tNode_isScalar
|
2020-04-22 16:22:47 +05:30
|
|
|
procedure :: &
|
|
|
|
asList => tNode_asList
|
2020-06-16 19:27:16 +05:30
|
|
|
procedure :: &
|
|
|
|
isList => tNode_isList
|
2020-04-22 16:22:47 +05:30
|
|
|
procedure :: &
|
|
|
|
asDict => tNode_asDict
|
2020-06-16 19:27:16 +05:30
|
|
|
procedure :: &
|
|
|
|
isDict => tNode_isDict
|
|
|
|
procedure :: &
|
2020-04-22 19:21:05 +05:30
|
|
|
tNode_get_byIndex => tNode_get_byIndex
|
2020-04-22 16:22:47 +05:30
|
|
|
procedure :: &
|
2020-04-22 19:21:05 +05:30
|
|
|
tNode_get_byIndex_asFloat => tNode_get_byIndex_asFloat
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byIndex_asFloats => tNode_get_byIndex_asFloats
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byIndex_asInt => tNode_get_byIndex_asInt
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byIndex_asInts => tNode_get_byIndex_asInts
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byIndex_asBool => tNode_get_byIndex_asBool
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byIndex_asBools => tNode_get_byIndex_asBools
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byIndex_asString => tNode_get_byIndex_asString
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byIndex_asStrings => tNode_get_byIndex_asStrings
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byKey => tNode_get_byKey
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byKey_asFloat => tNode_get_byKey_asFloat
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byKey_asFloats => tNode_get_byKey_asFloats
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byKey_asInt => tNode_get_byKey_asInt
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byKey_asInts => tNode_get_byKey_asInts
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byKey_asBool => tNode_get_byKey_asBool
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byKey_asBools => tNode_get_byKey_asBools
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byKey_asString => tNode_get_byKey_asString
|
|
|
|
procedure :: &
|
|
|
|
tNode_get_byKey_asStrings => tNode_get_byKey_asStrings
|
2020-05-08 02:40:27 +05:30
|
|
|
procedure :: &
|
2020-05-01 00:59:59 +05:30
|
|
|
getIndex => tNode_get_byKey_asIndex
|
2020-06-16 19:27:16 +05:30
|
|
|
procedure :: &
|
|
|
|
getKey => tNode_getKey_byIndex
|
|
|
|
procedure :: &
|
|
|
|
contains => tNode_contains
|
2020-08-15 19:32:10 +05:30
|
|
|
|
2020-04-22 16:22:47 +05:30
|
|
|
generic :: &
|
|
|
|
get => tNode_get_byIndex, &
|
|
|
|
tNode_get_byKey
|
|
|
|
generic :: &
|
|
|
|
get_asFloat => tNode_get_byIndex_asFloat, &
|
|
|
|
tNode_get_byKey_asFloat
|
|
|
|
generic :: &
|
|
|
|
get_asFloats => tNode_get_byIndex_asFloats, &
|
|
|
|
tNode_get_byKey_asFloats
|
|
|
|
generic :: &
|
|
|
|
get_asInt => tNode_get_byIndex_asInt, &
|
|
|
|
tNode_get_byKey_asInt
|
|
|
|
generic :: &
|
|
|
|
get_asInts => tNode_get_byIndex_asInts, &
|
|
|
|
tNode_get_byKey_asInts
|
|
|
|
generic :: &
|
|
|
|
get_asBool => tNode_get_byIndex_asBool, &
|
|
|
|
tNode_get_byKey_asBool
|
|
|
|
generic :: &
|
|
|
|
get_asBools => tNode_get_byIndex_asBools, &
|
|
|
|
tNode_get_byKey_asBools
|
|
|
|
generic :: &
|
|
|
|
get_asString => tNode_get_byIndex_asString, &
|
|
|
|
tNode_get_byKey_asString
|
|
|
|
generic :: &
|
|
|
|
get_asStrings => tNode_get_byIndex_asStrings, &
|
|
|
|
tNode_get_byKey_asStrings
|
|
|
|
end type tNode
|
|
|
|
|
|
|
|
|
2020-05-22 00:22:15 +05:30
|
|
|
type, extends(tNode), public :: tScalar
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-04-28 13:59:13 +05:30
|
|
|
character(len=:), allocatable, private :: value
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
contains
|
|
|
|
procedure :: asFormattedString => tScalar_asFormattedString
|
|
|
|
procedure :: &
|
|
|
|
asFloat => tScalar_asFloat
|
|
|
|
procedure :: &
|
|
|
|
asInt => tScalar_asInt
|
|
|
|
procedure :: &
|
|
|
|
asBool => tScalar_asBool
|
|
|
|
procedure :: &
|
|
|
|
asString => tScalar_asString
|
|
|
|
end type tScalar
|
|
|
|
|
2020-05-22 00:22:15 +05:30
|
|
|
type, extends(tNode), public :: tList
|
2020-04-28 13:59:13 +05:30
|
|
|
|
2020-04-22 16:22:47 +05:30
|
|
|
class(tItem), pointer :: first => null()
|
|
|
|
|
|
|
|
contains
|
|
|
|
procedure :: asFormattedString => tList_asFormattedString
|
|
|
|
procedure :: append => tList_append
|
|
|
|
procedure :: &
|
|
|
|
asFloats => tList_asFloats
|
|
|
|
procedure :: &
|
|
|
|
asInts => tList_asInts
|
|
|
|
procedure :: &
|
|
|
|
asBools => tList_asBools
|
|
|
|
procedure :: &
|
|
|
|
asStrings => tList_asStrings
|
|
|
|
final :: tList_finalize
|
|
|
|
end type tList
|
|
|
|
|
2020-05-22 00:22:15 +05:30
|
|
|
type, extends(tList), public :: tDict
|
2020-04-22 16:22:47 +05:30
|
|
|
contains
|
|
|
|
procedure :: asFormattedString => tDict_asFormattedString
|
|
|
|
procedure :: set => tDict_set
|
|
|
|
end type tDict
|
|
|
|
|
|
|
|
|
|
|
|
type :: tItem
|
|
|
|
character(len=:), allocatable :: key
|
2020-05-01 00:59:59 +05:30
|
|
|
class(tNode), pointer :: node => null()
|
2020-04-22 16:22:47 +05:30
|
|
|
class(tItem), pointer :: next => null()
|
2020-05-08 02:40:27 +05:30
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
contains
|
|
|
|
final :: tItem_finalize
|
2020-04-22 16:22:47 +05:30
|
|
|
end type tItem
|
|
|
|
|
2020-06-23 14:36:41 +05:30
|
|
|
type(tDict), target, public :: &
|
2020-06-16 19:27:16 +05:30
|
|
|
emptyDict
|
2020-06-23 14:36:41 +05:30
|
|
|
type(tList), target, public :: &
|
2020-06-16 19:27:16 +05:30
|
|
|
emptyList
|
|
|
|
|
2020-04-22 16:22:47 +05:30
|
|
|
abstract interface
|
|
|
|
|
2020-05-03 02:33:11 +05:30
|
|
|
recursive function asFormattedString(self,indent)
|
2020-04-22 16:22:47 +05:30
|
|
|
import tNode
|
2020-05-03 02:33:11 +05:30
|
|
|
character(len=:), allocatable :: asFormattedString
|
2020-04-22 16:22:47 +05:30
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
integer, intent(in), optional :: indent
|
2020-05-03 02:33:11 +05:30
|
|
|
end function asFormattedString
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
end interface
|
|
|
|
|
|
|
|
interface tScalar
|
|
|
|
module procedure tScalar_init__
|
|
|
|
end interface tScalar
|
|
|
|
|
|
|
|
interface assignment (=)
|
|
|
|
module procedure tScalar_assign__
|
|
|
|
end interface assignment (=)
|
|
|
|
|
2020-05-22 00:22:15 +05:30
|
|
|
public :: &
|
|
|
|
YAML_types_init, &
|
2020-08-15 19:32:10 +05:30
|
|
|
output_asStrings, & !ToDo: Hack for GNU. Remove later
|
2020-05-22 00:22:15 +05:30
|
|
|
assignment(=)
|
|
|
|
|
2020-04-22 16:22:47 +05:30
|
|
|
contains
|
|
|
|
|
2020-04-28 13:59:13 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-09-13 16:13:49 +05:30
|
|
|
!> @brief Do sanity checks.
|
2020-04-28 13:59:13 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
subroutine YAML_types_init
|
|
|
|
|
2020-09-17 22:58:41 +05:30
|
|
|
print'(/,a)', ' <<<+- YAML_types init -+>>>'
|
2020-04-28 13:59:13 +05:30
|
|
|
|
2020-05-16 20:35:03 +05:30
|
|
|
call selfTest
|
2020-04-28 13:59:13 +05:30
|
|
|
|
|
|
|
end subroutine YAML_types_init
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
|
2020-04-28 13:59:13 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-09-13 16:13:49 +05:30
|
|
|
!> @brief Check correctness of some type bound procedures.
|
2020-04-28 13:59:13 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-05-16 20:35:03 +05:30
|
|
|
subroutine selfTest
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
class(tNode), pointer :: s1,s2
|
|
|
|
allocate(tScalar::s1)
|
|
|
|
allocate(tScalar::s2)
|
|
|
|
select type(s1)
|
2020-05-08 02:40:27 +05:30
|
|
|
class is(tScalar)
|
2020-05-01 00:59:59 +05:30
|
|
|
s1 = '1'
|
2020-09-13 15:39:32 +05:30
|
|
|
if(s1%asInt() /= 1) error stop 'tScalar_asInt'
|
|
|
|
if(dNeq(s1%asFloat(),1.0_pReal)) error stop 'tScalar_asFloat'
|
2020-08-15 19:32:10 +05:30
|
|
|
s1 = 'true'
|
2020-09-13 15:39:32 +05:30
|
|
|
if(.not. s1%asBool()) error stop 'tScalar_asBool'
|
|
|
|
if(s1%asString() /= 'true') error stop 'tScalar_asString'
|
2020-05-01 00:59:59 +05:30
|
|
|
end select
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
block
|
2020-05-01 00:59:59 +05:30
|
|
|
class(tNode), pointer :: l1, l2, n
|
|
|
|
select type(s1)
|
|
|
|
class is(tScalar)
|
2020-05-01 01:04:11 +05:30
|
|
|
s1 = '2'
|
2020-05-01 00:59:59 +05:30
|
|
|
endselect
|
2020-05-08 02:40:27 +05:30
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
select type(s2)
|
|
|
|
class is(tScalar)
|
|
|
|
s2 = '3'
|
|
|
|
endselect
|
|
|
|
|
|
|
|
allocate(tList::l1)
|
|
|
|
select type(l1)
|
|
|
|
class is(tList)
|
|
|
|
call l1%append(s1)
|
|
|
|
call l1%append(s2)
|
|
|
|
n => l1
|
2020-09-13 15:39:32 +05:30
|
|
|
if(any(l1%asInts() /= [2,3])) error stop 'tList_asInts'
|
|
|
|
if(any(dNeq(l1%asFloats(),[2.0_pReal,3.0_pReal]))) error stop 'tList_asFloats'
|
|
|
|
if(n%get_asInt(1) /= 2) error stop 'byIndex_asInt'
|
|
|
|
if(dNeq(n%get_asFloat(2),3.0_pReal)) error stop 'byIndex_asFloat'
|
2020-05-01 00:59:59 +05:30
|
|
|
endselect
|
2020-05-08 02:40:27 +05:30
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
allocate(tList::l2)
|
|
|
|
select type(l2)
|
|
|
|
class is(tList)
|
|
|
|
call l2%append(l1)
|
2020-09-13 15:39:32 +05:30
|
|
|
if(any(l2%get_asInts(1) /= [2,3])) error stop 'byIndex_asInts'
|
|
|
|
if(any(dNeq(l2%get_asFloats(1),[2.0_pReal,3.0_pReal]))) error stop 'byIndex_asFloats'
|
2020-05-01 00:59:59 +05:30
|
|
|
n => l2
|
|
|
|
end select
|
|
|
|
deallocate(n)
|
2020-05-08 02:40:27 +05:30
|
|
|
end block
|
2020-05-01 00:59:59 +05:30
|
|
|
|
2020-05-08 02:40:27 +05:30
|
|
|
block
|
2020-05-01 00:59:59 +05:30
|
|
|
type(tList), target :: l1
|
|
|
|
type(tScalar),pointer :: s3,s4
|
|
|
|
class(tNode), pointer :: n
|
2020-05-08 02:40:27 +05:30
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
allocate(tScalar::s1)
|
|
|
|
allocate(tScalar::s2)
|
|
|
|
s3 => s1%asScalar()
|
|
|
|
s4 => s2%asScalar()
|
2020-08-15 19:32:10 +05:30
|
|
|
s3 = 'true'
|
2020-05-01 00:59:59 +05:30
|
|
|
s4 = 'False'
|
2020-05-08 02:40:27 +05:30
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
call l1%append(s1)
|
|
|
|
call l1%append(s2)
|
|
|
|
n => l1
|
2020-05-08 02:40:27 +05:30
|
|
|
|
2020-09-13 15:39:32 +05:30
|
|
|
if(any(l1%asBools() .neqv. [.true., .false.])) error stop 'tList_asBools'
|
|
|
|
if(any(l1%asStrings() /= ['true ','False'])) error stop 'tList_asStrings'
|
|
|
|
if(n%get_asBool(2)) error stop 'byIndex_asBool'
|
|
|
|
if(n%get_asString(1) /= 'true') error stop 'byIndex_asString'
|
2020-05-08 02:40:27 +05:30
|
|
|
end block
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-05-16 20:35:03 +05:30
|
|
|
end subroutine selfTest
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
|
|
|
|
!---------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief init from string
|
|
|
|
!---------------------------------------------------------------------------------------------------
|
|
|
|
type(tScalar) pure function tScalar_init__(value)
|
|
|
|
|
|
|
|
character(len=*), intent(in) :: value
|
|
|
|
|
|
|
|
tScalar_init__%value =value
|
|
|
|
|
|
|
|
end function tScalar_init__
|
|
|
|
|
|
|
|
|
|
|
|
!---------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief set value from string
|
|
|
|
!---------------------------------------------------------------------------------------------------
|
|
|
|
elemental pure subroutine tScalar_assign__(self,value)
|
|
|
|
|
|
|
|
type(tScalar), intent(out) :: self
|
|
|
|
character(len=*), intent(in) :: value
|
|
|
|
|
|
|
|
self%value = value
|
|
|
|
|
|
|
|
end subroutine tScalar_assign__
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Type guard, guarantee scalar
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_asScalar(self) result(scalar)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
class(tScalar), pointer :: scalar
|
|
|
|
|
|
|
|
select type(self)
|
|
|
|
class is(tScalar)
|
|
|
|
scalar => self
|
|
|
|
class default
|
2020-10-23 22:13:52 +05:30
|
|
|
call IO_error(706,ext_msg='Expected "scalar"')
|
2020-04-22 16:22:47 +05:30
|
|
|
end select
|
|
|
|
|
|
|
|
end function tNode_asScalar
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Type guard, guarantee list
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_asList(self) result(list)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
class(tList), pointer :: list
|
|
|
|
|
|
|
|
select type(self)
|
|
|
|
class is(tList)
|
|
|
|
list => self
|
|
|
|
class default
|
2020-10-23 22:13:52 +05:30
|
|
|
call IO_error(706,ext_msg='Expected "list"')
|
2020-04-22 16:22:47 +05:30
|
|
|
end select
|
|
|
|
|
|
|
|
end function tNode_asList
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Type guard, guarantee dict
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_asDict(self) result(dict)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
class(tDict), pointer :: dict
|
|
|
|
|
|
|
|
select type(self)
|
|
|
|
class is(tDict)
|
|
|
|
dict => self
|
|
|
|
class default
|
2020-10-23 22:13:52 +05:30
|
|
|
call IO_error(706,ext_msg='Expected "dict"')
|
2020-04-22 16:22:47 +05:30
|
|
|
end select
|
|
|
|
|
|
|
|
end function tNode_asDict
|
|
|
|
|
|
|
|
|
2020-06-16 19:27:16 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Checks if node is a scalar
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_isScalar(self) result(scalar)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
logical :: scalar
|
|
|
|
|
|
|
|
scalar = .false.
|
|
|
|
select type(self)
|
|
|
|
class is(tScalar)
|
|
|
|
scalar = .true.
|
|
|
|
end select
|
|
|
|
|
|
|
|
end function tNode_isScalar
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Checks if node is a list
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_isList(self) result(list)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
logical :: list
|
|
|
|
|
|
|
|
list = .false.
|
|
|
|
select type(self)
|
|
|
|
class is(tList)
|
|
|
|
list = .true.
|
|
|
|
end select
|
|
|
|
|
|
|
|
end function tNode_isList
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Checks if node is a dict
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_isDict(self) result(dict)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
logical :: dict
|
|
|
|
|
|
|
|
dict = .false.
|
|
|
|
select type(self)
|
|
|
|
class is(tDict)
|
|
|
|
dict = .true.
|
|
|
|
end select
|
|
|
|
|
|
|
|
end function tNode_isDict
|
|
|
|
|
|
|
|
|
2020-04-22 16:22:47 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by index
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_get_byIndex(self,i) result(node)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
integer, intent(in) :: i
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
|
|
|
|
class(tList), pointer :: self_
|
|
|
|
class(tItem), pointer :: item
|
|
|
|
integer :: j
|
|
|
|
|
|
|
|
self_ => self%asList()
|
2020-06-18 03:47:43 +05:30
|
|
|
if(i < 1 .or. i > self_%length) call IO_error(150,ext_msg='tNode_get_byIndex')
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
j = 1
|
|
|
|
item => self_%first
|
|
|
|
do while(j<i)
|
|
|
|
item => item%next
|
|
|
|
j = j + 1
|
|
|
|
enddo
|
|
|
|
node => item%node
|
|
|
|
|
|
|
|
end function tNode_get_byIndex
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by index and convert to float
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_get_byIndex_asFloat(self,i) result(nodeAsFloat)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
integer, intent(in) :: i
|
|
|
|
real(pReal) :: nodeAsFloat
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
type(tScalar), pointer :: scalar
|
|
|
|
|
|
|
|
node => self%get(i)
|
|
|
|
scalar => node%asScalar()
|
|
|
|
nodeAsFloat = scalar%asFloat()
|
|
|
|
|
|
|
|
end function tNode_get_byIndex_asFloat
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by index and convert to int
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_get_byIndex_asInt(self,i) result(nodeAsInt)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
integer, intent(in) :: i
|
|
|
|
integer :: nodeAsInt
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
type(tScalar), pointer :: scalar
|
|
|
|
|
|
|
|
node => self%get(i)
|
|
|
|
scalar => node%asScalar()
|
|
|
|
nodeAsInt = scalar%asInt()
|
|
|
|
|
|
|
|
end function tNode_get_byIndex_asInt
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by index and convert to bool
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_get_byIndex_asBool(self,i) result(nodeAsBool)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
integer, intent(in) :: i
|
|
|
|
logical :: nodeAsBool
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
type(tScalar), pointer :: scalar
|
|
|
|
|
|
|
|
node => self%get(i)
|
|
|
|
scalar => node%asScalar()
|
|
|
|
nodeAsBool = scalar%asBool()
|
|
|
|
|
|
|
|
end function tNode_get_byIndex_asBool
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by index and convert to string
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_get_byIndex_asString(self,i) result(nodeAsString)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
integer, intent(in) :: i
|
|
|
|
character(len=:), allocatable :: nodeAsString
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
type(tScalar), pointer :: scalar
|
|
|
|
|
|
|
|
node => self%get(i)
|
|
|
|
scalar => node%asScalar()
|
|
|
|
nodeAsString = scalar%asString()
|
|
|
|
|
|
|
|
end function tNode_get_byIndex_asString
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by index and convert to float array
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_get_byIndex_asFloats(self,i) result(nodeAsFloats)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
integer, intent(in) :: i
|
|
|
|
real(pReal), dimension(:), allocatable :: nodeAsFloats
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
class(tList), pointer :: list
|
|
|
|
|
|
|
|
node => self%get(i)
|
|
|
|
list => node%asList()
|
|
|
|
nodeAsFloats = list%asFloats()
|
|
|
|
|
|
|
|
end function tNode_get_byIndex_asFloats
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by index and convert to int array
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_get_byIndex_asInts(self,i) result(nodeAsInts)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
integer, intent(in) :: i
|
|
|
|
integer, dimension(:), allocatable :: nodeAsInts
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
class(tList), pointer :: list
|
|
|
|
|
|
|
|
node => self%get(i)
|
|
|
|
list => node%asList()
|
|
|
|
nodeAsInts = list%asInts()
|
|
|
|
|
|
|
|
end function tNode_get_byIndex_asInts
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by index and convert to bool array
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_get_byIndex_asBools(self,i) result(nodeAsBools)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
integer, intent(in) :: i
|
|
|
|
logical, dimension(:), allocatable :: nodeAsBools
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
class(tList), pointer :: list
|
|
|
|
|
|
|
|
node => self%get(i)
|
|
|
|
list => node%asList()
|
|
|
|
nodeAsBools = list%asBools()
|
|
|
|
|
|
|
|
end function tNode_get_byIndex_asBools
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by index and convert to string array
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_get_byIndex_asStrings(self,i) result(nodeAsStrings)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
integer, intent(in) :: i
|
|
|
|
character(len=:), allocatable, dimension(:) :: nodeAsStrings
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
type(tList), pointer :: list
|
|
|
|
|
|
|
|
node => self%get(i)
|
|
|
|
list => node%asList()
|
|
|
|
nodeAsStrings = list%asStrings()
|
|
|
|
|
|
|
|
end function tNode_get_byIndex_asStrings
|
|
|
|
|
|
|
|
|
2020-10-24 20:56:24 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-06-16 19:27:16 +05:30
|
|
|
!> @brief Returns the key in a dictionary as a string
|
2020-10-24 20:56:24 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-06-16 19:27:16 +05:30
|
|
|
function tNode_getKey_byIndex(self,i) result(key)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
integer, intent(in) :: i
|
|
|
|
|
|
|
|
character(len=:), allocatable :: key
|
|
|
|
integer :: j
|
|
|
|
type(tDict), pointer :: dict
|
|
|
|
type(tItem), pointer :: item
|
|
|
|
|
|
|
|
dict => self%asDict()
|
|
|
|
item => dict%first
|
|
|
|
do j = 1, dict%length
|
|
|
|
if(j == i) then
|
|
|
|
key = item%key
|
|
|
|
exit
|
|
|
|
else
|
|
|
|
item => item%next
|
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
|
|
|
|
end function tNode_getKey_byIndex
|
|
|
|
|
|
|
|
|
|
|
|
!-------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Checks if a given key/item is present in the dict/list
|
|
|
|
!-------------------------------------------------------------------------------------------------
|
|
|
|
function tNode_contains(self,k) result(exists)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
character(len=*), intent(in) :: k
|
|
|
|
|
|
|
|
logical :: exists
|
|
|
|
integer :: j
|
|
|
|
type(tList), pointer :: list
|
|
|
|
type(tDict), pointer :: dict
|
|
|
|
|
|
|
|
exists = .false.
|
|
|
|
if(self%isDict()) then
|
|
|
|
dict => self%asDict()
|
|
|
|
do j=1, dict%length
|
|
|
|
if(dict%getKey(j) == k) then
|
|
|
|
exists = .true.
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
elseif(self%isList()) then
|
|
|
|
list => self%asList()
|
|
|
|
do j =1, list%length
|
|
|
|
if(list%get_asString(j) == k) then
|
|
|
|
exists = .true.
|
|
|
|
return
|
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
else
|
2020-10-23 22:13:52 +05:30
|
|
|
call IO_error(706,ext_msg='Expected "list" or "dict"')
|
2020-06-16 19:27:16 +05:30
|
|
|
endif
|
|
|
|
|
|
|
|
end function tNode_contains
|
|
|
|
|
|
|
|
|
2020-04-22 16:22:47 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-06-16 19:27:16 +05:30
|
|
|
!> @brief Access by key
|
2020-04-22 16:22:47 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-06-16 19:27:16 +05:30
|
|
|
function tNode_get_byKey(self,k,defaultVal) result(node)
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-06-16 19:27:16 +05:30
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
character(len=*), intent(in) :: k
|
|
|
|
class(tNode), intent(in),optional,target :: defaultVal
|
|
|
|
class(tNode), pointer :: node
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-05-08 02:40:27 +05:30
|
|
|
type(tDict), pointer :: self_
|
2020-04-22 16:22:47 +05:30
|
|
|
type(tItem), pointer :: item
|
|
|
|
integer :: j
|
2020-06-16 19:27:16 +05:30
|
|
|
logical :: found
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-06-16 19:27:16 +05:30
|
|
|
found = present(defaultVal)
|
|
|
|
if(found) node => defaultVal
|
|
|
|
|
2020-04-22 16:22:47 +05:30
|
|
|
self_ => self%asDict()
|
|
|
|
|
|
|
|
j = 1
|
|
|
|
item => self_%first
|
|
|
|
do while(j <= self_%length)
|
2020-06-16 19:27:16 +05:30
|
|
|
if (item%key == k) then
|
|
|
|
found = .true.
|
|
|
|
exit
|
|
|
|
endif
|
2020-04-22 16:22:47 +05:30
|
|
|
item => item%next
|
|
|
|
j = j + 1
|
|
|
|
enddo
|
2020-06-16 19:27:16 +05:30
|
|
|
|
|
|
|
if (.not. found) then
|
|
|
|
call IO_error(143,ext_msg=k)
|
|
|
|
else
|
|
|
|
if(associated(item)) node => item%node
|
|
|
|
endif
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
end function tNode_get_byKey
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by key and convert to float
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-06-16 19:27:16 +05:30
|
|
|
function tNode_get_byKey_asFloat(self,k,defaultVal) result(nodeAsFloat)
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-06-16 19:27:16 +05:30
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
character(len=*), intent(in) :: k
|
|
|
|
real(pReal), intent(in),optional :: defaultVal
|
2020-04-22 16:22:47 +05:30
|
|
|
real(pReal) :: nodeAsFloat
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
type(tScalar), pointer :: scalar
|
|
|
|
|
2020-06-16 19:27:16 +05:30
|
|
|
if(self%contains(k)) then
|
|
|
|
node => self%get(k)
|
|
|
|
scalar => node%asScalar()
|
|
|
|
nodeAsFloat = scalar%asFloat()
|
|
|
|
elseif(present(defaultVal)) then
|
|
|
|
nodeAsFloat = defaultVal
|
|
|
|
else
|
|
|
|
call IO_error(143,ext_msg=k)
|
|
|
|
endif
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
end function tNode_get_byKey_asFloat
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by key and convert to int
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-06-16 19:27:16 +05:30
|
|
|
function tNode_get_byKey_asInt(self,k,defaultVal) result(nodeAsInt)
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-06-16 19:27:16 +05:30
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
character(len=*), intent(in) :: k
|
|
|
|
integer, intent(in),optional :: defaultVal
|
2020-04-22 16:22:47 +05:30
|
|
|
integer :: nodeAsInt
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
type(tScalar), pointer :: scalar
|
|
|
|
|
2020-06-16 19:27:16 +05:30
|
|
|
if(self%contains(k)) then
|
|
|
|
node => self%get(k)
|
|
|
|
scalar => node%asScalar()
|
|
|
|
nodeAsInt = scalar%asInt()
|
|
|
|
elseif(present(defaultVal)) then
|
|
|
|
nodeAsInt = defaultVal
|
|
|
|
else
|
|
|
|
call IO_error(143,ext_msg=k)
|
|
|
|
endif
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
end function tNode_get_byKey_asInt
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by key and convert to bool
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-06-16 19:27:16 +05:30
|
|
|
function tNode_get_byKey_asBool(self,k,defaultVal) result(nodeAsBool)
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-06-16 19:27:16 +05:30
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
character(len=*), intent(in) :: k
|
|
|
|
logical, intent(in),optional :: defaultVal
|
2020-04-22 16:22:47 +05:30
|
|
|
logical :: nodeAsBool
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
type(tScalar), pointer :: scalar
|
|
|
|
|
2020-06-16 19:27:16 +05:30
|
|
|
if(self%contains(k)) then
|
|
|
|
node => self%get(k)
|
|
|
|
scalar => node%asScalar()
|
|
|
|
nodeAsBool = scalar%asBool()
|
|
|
|
elseif(present(defaultVal)) then
|
|
|
|
nodeAsBool = defaultVal
|
|
|
|
else
|
|
|
|
call IO_error(143,ext_msg=k)
|
|
|
|
endif
|
|
|
|
|
2020-04-22 16:22:47 +05:30
|
|
|
end function tNode_get_byKey_asBool
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by key and convert to string
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-06-16 19:27:16 +05:30
|
|
|
function tNode_get_byKey_asString(self,k,defaultVal) result(nodeAsString)
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-06-16 19:27:16 +05:30
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
character(len=*), intent(in) :: k
|
|
|
|
character(len=*), intent(in),optional :: defaultVal
|
2020-04-22 16:22:47 +05:30
|
|
|
character(len=:), allocatable :: nodeAsString
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
type(tScalar), pointer :: scalar
|
|
|
|
|
2020-06-16 19:27:16 +05:30
|
|
|
if(self%contains(k)) then
|
|
|
|
node => self%get(k)
|
|
|
|
scalar => node%asScalar()
|
|
|
|
nodeAsString = scalar%asString()
|
|
|
|
elseif(present(defaultVal)) then
|
|
|
|
nodeAsString = defaultVal
|
|
|
|
else
|
|
|
|
call IO_error(143,ext_msg=k)
|
|
|
|
endif
|
|
|
|
|
2020-04-22 16:22:47 +05:30
|
|
|
end function tNode_get_byKey_asString
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by key and convert to float array
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-08-15 19:32:10 +05:30
|
|
|
function tNode_get_byKey_asFloats(self,k,defaultVal,requiredSize) result(nodeAsFloats)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
character(len=*), intent(in) :: k
|
|
|
|
real(pReal), intent(in), dimension(:), optional :: defaultVal
|
|
|
|
integer, intent(in), optional :: requiredSize
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
real(pReal), dimension(:), allocatable :: nodeAsFloats
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
type(tList), pointer :: list
|
2020-04-28 13:59:13 +05:30
|
|
|
|
2020-08-15 19:32:10 +05:30
|
|
|
if(self%contains(k)) then
|
|
|
|
node => self%get(k)
|
|
|
|
list => node%asList()
|
|
|
|
nodeAsFloats = list%asFloats()
|
|
|
|
elseif(present(defaultVal)) then
|
|
|
|
nodeAsFloats = defaultVal
|
|
|
|
else
|
|
|
|
call IO_error(143,ext_msg=k)
|
|
|
|
endif
|
|
|
|
|
|
|
|
if(present(requiredSize)) then
|
|
|
|
if(requiredSize /= size(nodeAsFloats)) call IO_error(146,ext_msg=k)
|
|
|
|
endif
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
end function tNode_get_byKey_asFloats
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by key and convert to int array
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-08-15 19:32:10 +05:30
|
|
|
function tNode_get_byKey_asInts(self,k,defaultVal,requiredSize) result(nodeAsInts)
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-08-15 19:32:10 +05:30
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
character(len=*), intent(in) :: k
|
|
|
|
integer, dimension(:), intent(in), optional :: defaultVal
|
|
|
|
integer, intent(in), optional :: requiredSize
|
2020-04-22 16:22:47 +05:30
|
|
|
integer, dimension(:), allocatable :: nodeAsInts
|
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
type(tList), pointer :: list
|
|
|
|
|
2020-08-15 19:32:10 +05:30
|
|
|
if(self%contains(k)) then
|
|
|
|
node => self%get(k)
|
|
|
|
list => node%asList()
|
|
|
|
nodeAsInts = list%asInts()
|
|
|
|
elseif(present(defaultVal)) then
|
|
|
|
nodeAsInts = defaultVal
|
|
|
|
else
|
|
|
|
call IO_error(143,ext_msg=k)
|
|
|
|
endif
|
|
|
|
|
|
|
|
if(present(requiredSize)) then
|
|
|
|
if(requiredSize /= size(nodeAsInts)) call IO_error(146,ext_msg=k)
|
|
|
|
endif
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
end function tNode_get_byKey_asInts
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by key and convert to bool array
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-08-15 19:32:10 +05:30
|
|
|
function tNode_get_byKey_asBools(self,k,defaultVal) result(nodeAsBools)
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-08-15 19:32:10 +05:30
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
character(len=*), intent(in) :: k
|
|
|
|
logical, dimension(:), intent(in), optional :: defaultVal
|
|
|
|
logical, dimension(:), allocatable :: nodeAsBools
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
type(tList), pointer :: list
|
|
|
|
|
2020-08-15 19:32:10 +05:30
|
|
|
if(self%contains(k)) then
|
|
|
|
node => self%get(k)
|
|
|
|
list => node%asList()
|
|
|
|
nodeAsBools = list%asBools()
|
|
|
|
elseif(present(defaultVal)) then
|
|
|
|
nodeAsBools = defaultVal
|
|
|
|
else
|
|
|
|
call IO_error(143,ext_msg=k)
|
|
|
|
endif
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
end function tNode_get_byKey_asBools
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Access by key and convert to string array
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-08-15 19:32:10 +05:30
|
|
|
function tNode_get_byKey_asStrings(self,k,defaultVal) result(nodeAsStrings)
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-08-15 19:32:10 +05:30
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
character(len=*), intent(in) :: k
|
|
|
|
character(len=*), intent(in), dimension(:), optional :: defaultVal
|
|
|
|
character(len=:), allocatable, dimension(:) :: nodeAsStrings
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
class(tNode), pointer :: node
|
|
|
|
type(tList), pointer :: list
|
|
|
|
|
2020-08-15 19:32:10 +05:30
|
|
|
if(self%contains(k)) then
|
|
|
|
node => self%get(k)
|
|
|
|
list => node%asList()
|
|
|
|
nodeAsStrings = list%asStrings()
|
|
|
|
elseif(present(defaultVal)) then
|
|
|
|
nodeAsStrings = defaultVal
|
|
|
|
else
|
|
|
|
call IO_error(143,ext_msg=k)
|
|
|
|
endif
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
end function tNode_get_byKey_asStrings
|
|
|
|
|
|
|
|
|
2020-08-15 19:32:10 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Returns string output array (hack for GNU)
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function output_asStrings(self) result(output) !ToDo: SR: Remove whenever GNU works
|
|
|
|
|
|
|
|
class(tNode), pointer,intent(in) :: self
|
|
|
|
character(len=pStringLen), allocatable, dimension(:) :: output
|
|
|
|
|
|
|
|
class(tNode), pointer :: output_list
|
|
|
|
integer :: o
|
|
|
|
|
|
|
|
output_list => self%get('output',defaultVal=emptyList)
|
|
|
|
allocate(output(output_list%length))
|
|
|
|
do o = 1, output_list%length
|
|
|
|
output(o) = output_list%get_asString(o)
|
|
|
|
enddo
|
|
|
|
|
|
|
|
|
|
|
|
end function output_asStrings
|
|
|
|
|
|
|
|
|
2020-05-08 02:40:27 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-05-01 00:59:59 +05:30
|
|
|
!> @brief Returns the index of a key in a dictionary
|
2020-05-08 02:40:27 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-05-01 00:59:59 +05:30
|
|
|
function tNode_get_byKey_asIndex(self,key) result(keyIndex)
|
|
|
|
|
|
|
|
class(tNode), intent(in), target :: self
|
|
|
|
character(len=*), intent(in) :: key
|
|
|
|
|
|
|
|
integer :: keyIndex
|
|
|
|
integer :: i
|
|
|
|
type(tDict), pointer :: dict
|
|
|
|
type(tItem), pointer :: item
|
|
|
|
|
|
|
|
dict => self%asDict()
|
|
|
|
item => dict%first
|
2020-05-08 02:40:27 +05:30
|
|
|
keyIndex = -1
|
2020-05-01 00:59:59 +05:30
|
|
|
do i = 1, dict%length
|
|
|
|
if(key == item%key) then
|
|
|
|
keyIndex = i
|
|
|
|
exit
|
|
|
|
else
|
|
|
|
item => item%next
|
|
|
|
endif
|
|
|
|
enddo
|
|
|
|
|
2020-10-01 05:21:31 +05:30
|
|
|
if(keyIndex == -1) call IO_error(140,ext_msg=key)
|
2020-10-01 03:03:09 +05:30
|
|
|
|
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
end function tNode_get_byKey_asIndex
|
|
|
|
|
|
|
|
|
2020-04-22 16:22:47 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-05-08 02:40:27 +05:30
|
|
|
!> @brief Scalar as string (YAML block style)
|
2020-04-22 16:22:47 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-05-03 02:33:11 +05:30
|
|
|
recursive function tScalar_asFormattedString(self,indent)
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-05-03 02:33:11 +05:30
|
|
|
character(len=:), allocatable :: tScalar_asFormattedString
|
2020-05-01 00:59:59 +05:30
|
|
|
class (tScalar), intent(in), target :: self
|
|
|
|
integer, intent(in), optional :: indent
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-05-03 02:33:11 +05:30
|
|
|
tScalar_asFormattedString = trim(self%value)//IO_EOL
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-05-03 02:33:11 +05:30
|
|
|
end function tScalar_asFormattedString
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-05-08 02:40:27 +05:30
|
|
|
!> @brief List as string (YAML block style)
|
2020-04-22 16:22:47 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-05-03 02:33:11 +05:30
|
|
|
recursive function tList_asFormattedString(self,indent) result(str)
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
class (tList),intent(in),target :: self
|
|
|
|
integer, intent(in),optional :: indent
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
type (tItem), pointer :: item
|
2020-05-03 02:33:11 +05:30
|
|
|
character(len=:), allocatable :: str
|
2020-05-01 00:59:59 +05:30
|
|
|
integer :: i, indent_
|
2020-05-08 02:40:27 +05:30
|
|
|
|
2020-05-03 02:47:53 +05:30
|
|
|
str = ''
|
2020-04-22 16:22:47 +05:30
|
|
|
if(present(indent)) then
|
|
|
|
indent_ = indent
|
|
|
|
else
|
|
|
|
indent_ = 0
|
|
|
|
endif
|
|
|
|
|
|
|
|
item => self%first
|
|
|
|
do i = 1, self%length
|
2020-05-03 02:33:11 +05:30
|
|
|
if(i /= 1) str = str//repeat(' ',indent_)
|
|
|
|
str = str//'- '//item%node%asFormattedString(indent_+2)
|
2020-04-22 16:22:47 +05:30
|
|
|
item => item%next
|
2020-05-01 00:59:59 +05:30
|
|
|
end do
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-05-03 02:33:11 +05:30
|
|
|
end function tList_asFormattedString
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-05-08 02:40:27 +05:30
|
|
|
!> @brief Dictionary as string (YAML block style)
|
2020-04-22 16:22:47 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-05-03 02:33:11 +05:30
|
|
|
recursive function tDict_asFormattedString(self,indent) result(str)
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
class (tDict),intent(in),target :: self
|
|
|
|
integer, intent(in),optional :: indent
|
2020-05-08 02:40:27 +05:30
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
type (tItem),pointer :: item
|
2020-05-08 02:40:27 +05:30
|
|
|
character(len=:), allocatable :: str
|
2020-05-01 00:59:59 +05:30
|
|
|
integer :: i, indent_
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-05-03 02:47:53 +05:30
|
|
|
str = ''
|
2020-04-22 16:22:47 +05:30
|
|
|
if(present(indent)) then
|
|
|
|
indent_ = indent
|
|
|
|
else
|
|
|
|
indent_ = 0
|
|
|
|
endif
|
|
|
|
|
|
|
|
item => self%first
|
|
|
|
do i = 1, self%length
|
2020-05-08 02:40:27 +05:30
|
|
|
if(i /= 1) str = str//repeat(' ',indent_)
|
2020-05-03 02:33:11 +05:30
|
|
|
select type(node_1 =>item%node)
|
|
|
|
class is(tScalar)
|
|
|
|
str = str//trim(item%key)//': '//item%node%asFormattedString(indent_+len_trim(item%key)+2)
|
2020-05-01 00:59:59 +05:30
|
|
|
class default
|
2020-05-03 02:33:11 +05:30
|
|
|
str = str//trim(item%key)//':'//IO_EOL//repeat(' ',indent_+2)//item%node%asFormattedString(indent_+2)
|
|
|
|
endselect
|
2020-04-22 16:22:47 +05:30
|
|
|
item => item%next
|
2020-05-01 00:59:59 +05:30
|
|
|
end do
|
2020-04-22 16:22:47 +05:30
|
|
|
|
2020-05-03 02:33:11 +05:30
|
|
|
end function tDict_asFormattedString
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Convert to float
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tScalar_asFloat(self)
|
|
|
|
|
|
|
|
class(tScalar), intent(in), target :: self
|
|
|
|
real(pReal) :: tScalar_asFloat
|
|
|
|
|
|
|
|
tScalar_asFloat = IO_stringAsFloat(self%value)
|
|
|
|
|
|
|
|
end function tScalar_asFloat
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Convert to int
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tScalar_asInt(self)
|
|
|
|
|
|
|
|
class(tScalar), intent(in), target :: self
|
|
|
|
integer :: tScalar_asInt
|
|
|
|
|
|
|
|
tScalar_asInt = IO_stringAsInt(self%value)
|
|
|
|
|
|
|
|
end function tScalar_asInt
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Convert to bool
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tScalar_asBool(self)
|
|
|
|
|
|
|
|
class(tScalar), intent(in), target :: self
|
|
|
|
logical :: tScalar_asBool
|
|
|
|
|
|
|
|
tScalar_asBool = IO_stringAsBool(self%value)
|
|
|
|
|
|
|
|
end function tScalar_asBool
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Convert to string
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tScalar_asString(self)
|
|
|
|
|
|
|
|
class(tScalar), intent(in), target :: self
|
|
|
|
character(len=:), allocatable :: tScalar_asString
|
|
|
|
|
|
|
|
tScalar_asString = self%value
|
|
|
|
|
|
|
|
end function tScalar_asString
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Convert to float array
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tList_asFloats(self)
|
|
|
|
|
|
|
|
class(tList), intent(in), target :: self
|
|
|
|
real(pReal), dimension(:), allocatable :: tList_asFloats
|
|
|
|
|
|
|
|
integer :: i
|
|
|
|
type(tItem), pointer :: item
|
|
|
|
type(tScalar), pointer :: scalar
|
|
|
|
|
|
|
|
allocate(tList_asFloats(self%length))
|
|
|
|
item => self%first
|
|
|
|
do i = 1, self%length
|
|
|
|
scalar => item%node%asScalar()
|
|
|
|
tList_asFloats(i) = scalar%asFloat()
|
|
|
|
item => item%next
|
|
|
|
enddo
|
|
|
|
|
|
|
|
end function tList_asFloats
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Convert to int array
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tList_asInts(self)
|
|
|
|
|
|
|
|
class(tList), intent(in), target :: self
|
|
|
|
integer, dimension(:), allocatable :: tList_asInts
|
|
|
|
|
|
|
|
integer :: i
|
|
|
|
type(tItem), pointer :: item
|
|
|
|
type(tScalar), pointer :: scalar
|
|
|
|
|
|
|
|
allocate(tList_asInts(self%length))
|
|
|
|
item => self%first
|
|
|
|
do i = 1, self%length
|
|
|
|
scalar => item%node%asScalar()
|
|
|
|
tList_asInts(i) = scalar%asInt()
|
|
|
|
item => item%next
|
|
|
|
enddo
|
|
|
|
|
|
|
|
end function tList_asInts
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Convert to bool array
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tList_asBools(self)
|
|
|
|
|
|
|
|
class(tList), intent(in), target :: self
|
|
|
|
logical, dimension(:), allocatable :: tList_asBools
|
|
|
|
|
|
|
|
integer :: i
|
|
|
|
type(tItem), pointer :: item
|
|
|
|
type(tScalar), pointer :: scalar
|
|
|
|
|
|
|
|
allocate(tList_asBools(self%length))
|
|
|
|
item => self%first
|
|
|
|
do i = 1, self%length
|
|
|
|
scalar => item%node%asScalar()
|
|
|
|
tList_asBools(i) = scalar%asBool()
|
|
|
|
item => item%next
|
|
|
|
enddo
|
|
|
|
|
|
|
|
end function tList_asBools
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Convert to string array
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
function tList_asStrings(self)
|
|
|
|
|
|
|
|
class(tList), intent(in), target :: self
|
|
|
|
character(len=:), allocatable, dimension(:) :: tList_asStrings
|
|
|
|
|
|
|
|
integer :: i,len_max
|
|
|
|
type(tItem), pointer :: item
|
|
|
|
type(tScalar), pointer :: scalar
|
|
|
|
|
|
|
|
len_max = 0
|
|
|
|
item => self%first
|
|
|
|
do i = 1, self%length
|
|
|
|
scalar => item%node%asScalar()
|
2020-10-24 20:56:24 +05:30
|
|
|
len_max = max(len_max, len_trim(scalar%asString()))
|
2020-04-22 16:22:47 +05:30
|
|
|
item => item%next
|
|
|
|
enddo
|
|
|
|
|
2020-10-24 20:56:24 +05:30
|
|
|
allocate(character(len=len_max) :: tList_asStrings(self%length))
|
|
|
|
item => self%first
|
|
|
|
do i = 1, self%length
|
|
|
|
scalar => item%node%asScalar()
|
|
|
|
tList_asStrings(i) = scalar%asString()
|
|
|
|
item => item%next
|
|
|
|
enddo
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
end function tList_asStrings
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Append element
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
subroutine tList_append(self,node)
|
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
class(tList), intent(inout) :: self
|
|
|
|
class(tNode), intent(in), target :: node
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
type(tItem), pointer :: item
|
|
|
|
|
|
|
|
if (.not. associated(self%first)) then
|
|
|
|
allocate(self%first)
|
|
|
|
item => self%first
|
|
|
|
else
|
|
|
|
item => self%first
|
|
|
|
do while (associated(item%next))
|
|
|
|
item => item%next
|
|
|
|
end do
|
|
|
|
allocate(item%next)
|
|
|
|
item => item%next
|
|
|
|
end if
|
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
item%node => node
|
2020-04-22 16:22:47 +05:30
|
|
|
self%length = self%length + 1
|
|
|
|
|
|
|
|
end subroutine tList_append
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief Set the value of a key (either replace or add new)
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
subroutine tDict_set(self,key,node)
|
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
class (tDict), intent(inout) :: self
|
|
|
|
character(len=*), intent(in) :: key
|
|
|
|
class(tNode), intent(in), target :: node
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
type(tItem), pointer :: item
|
|
|
|
|
2020-04-28 13:59:13 +05:30
|
|
|
if (.not. associated(self%first)) then
|
2020-04-22 16:22:47 +05:30
|
|
|
allocate(self%first)
|
|
|
|
item => self%first
|
|
|
|
self%length = 1
|
|
|
|
else
|
|
|
|
item => self%first
|
|
|
|
searchExisting: do while (associated(item%next))
|
|
|
|
if (item%key == key) exit
|
|
|
|
item => item%next
|
|
|
|
end do searchExisting
|
|
|
|
if (.not. item%key == key) then
|
|
|
|
allocate(item%next)
|
|
|
|
item => item%next
|
|
|
|
self%length = self%length + 1
|
|
|
|
end if
|
|
|
|
end if
|
|
|
|
|
|
|
|
item%key = key
|
2020-05-01 00:59:59 +05:30
|
|
|
item%node => node
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
end subroutine tDict_set
|
|
|
|
|
|
|
|
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
2020-04-24 20:20:42 +05:30
|
|
|
!> @brief empties lists and dicts and free associated memory
|
2020-04-22 16:22:47 +05:30
|
|
|
!> @details called when variable goes out of scope.
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
recursive subroutine tList_finalize(self)
|
|
|
|
|
|
|
|
type (tList),intent(inout) :: self
|
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
deallocate(self%first)
|
2020-04-22 16:22:47 +05:30
|
|
|
|
|
|
|
end subroutine tList_finalize
|
|
|
|
|
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
!> @brief empties nodes and frees associated memory
|
|
|
|
!--------------------------------------------------------------------------------------------------
|
|
|
|
recursive subroutine tItem_finalize(self)
|
|
|
|
|
|
|
|
type(tItem),intent(inout) :: self
|
2020-05-08 02:40:27 +05:30
|
|
|
|
2020-05-01 00:59:59 +05:30
|
|
|
deallocate(self%node)
|
|
|
|
if(associated(self%next)) deallocate(self%next)
|
|
|
|
|
|
|
|
end subroutine tItem_finalize
|
|
|
|
|
2020-04-28 13:59:13 +05:30
|
|
|
end module YAML_types
|