recursive subroutine get_by_path(this, path, p)
use fson_value_m, only: fson_value, fson_value_get
implicit none
type(fson_value), pointer :: this, p
character(len=*), intent(inout) :: path
integer :: i, length, child_i
character :: c
logical :: array
! default to assuming relative to this
p => this
child_i = 1
array = .false.
length = len_trim(path)
do i=1, length
c = path(i:i)
select case (c)
case ("$")
! root
do while (associated (p % parent))
p => p % parent
end do
child_i = i + 1
case ("@")
! this
p => this
child_i = i + 1
case (".", "[")
! get child member from p
if (child_i < i) then
p => fson_value_get(p, path(child_i:i-1))
else
child_i = i + 1
cycle
end if
if (.not.associated(p)) then
return
end if
child_i = i + 1
! check if this is an array
! if so set the array flag
if (c == "[") then
! start looking for the array element index
array = .true.
end if
case ("]")
if (.not.array) then
print *, "ERROR: Unexpected ], not missing preceding ["
call exit(1)
end if
array = .false.
child_i = parse_integer(path(child_i:i-1))
p => fson_value_get(p, child_i)
child_i = i + 1
end select
end do
! grab the last child if present in the path
if (child_i <= length) then
p => fson_value_get(p, path(child_i:i-1))
if (.not.associated(p)) then
return
else
end if
end if
end subroutine get_by_path