get_by_path Subroutine

private recursive subroutine get_by_path(this, path, p)

Arguments

Type IntentOptional AttributesName
type(fson_value), pointer:: this
character(len=*), intent(inout) :: path
type(fson_value), pointer:: p

Contents

Source Code


Source Code

  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