Destroy a json_value linked-list structure.
The original FSON version of this routine was not properly freeing the memory. It was rewritten.
This routine destroys this variable, it’s children, and
(if destroy_next
is true) the subsequent elements in
an object or array. It does not destroy the parent or
previous elements.
There is some protection here to enable destruction of improperly-created linked lists. However, likely there are cases not handled. Use the json_value_validate method to validate a JSON structure that was manually created using json_value pointers.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(json_core), | intent(inout) | :: | json | |||
type(json_value), | pointer | :: | p | variable to destroy |
||
logical(kind=LK), | intent(in), | optional | :: | destroy_next | if true, then |
pure recursive subroutine json_value_destroy(json,p,destroy_next)
implicit none
class(json_core),intent(inout) :: json
type(json_value),pointer :: p !! variable to destroy
logical(LK),intent(in),optional :: destroy_next !! if true, then `p%next`
!! is also destroyed (default is true)
logical(LK) :: des_next !! local copy of `destroy_next`
!! optional argument
type(json_value),pointer :: child !! for getting child elements
logical :: circular !! to check to malformed linked lists
if (associated(p)) then
if (present(destroy_next)) then
des_next = destroy_next
else
des_next = .true.
end if
if (allocated(p%name)) deallocate(p%name)
call destroy_json_data(p)
if (associated(p%next)) then
! check for circular references:
if (associated(p, p%next)) nullify(p%next)
end if
if (associated(p%children)) then
do while (p%n_children > 0)
child => p%children
if (associated(child)) then
p%children => p%children%next
p%n_children = p%n_children - 1
! check children for circular references:
circular = (associated(p%children) .and. &
associated(p%children,child))
call json%destroy(child,destroy_next=.false.)
if (circular) exit
else
! it is a malformed JSON object. But, we will
! press ahead with the destroy process, since
! otherwise, there would be no way to destroy it.
exit
end if
end do
nullify(p%children)
nullify(child)
end if
if (associated(p%next) .and. des_next) call json%destroy(p%next)
nullify(p%previous)
nullify(p%parent)
nullify(p%tail)
if (associated(p)) deallocate(p)
nullify(p)
end if
end subroutine json_value_destroy