@@ -510,15 +510,6 @@ end subroutine traverse_callback_func
510510 end interface json_get_child
511511 ! *************************************************************************************
512512
513- ! *************************************************************************************
514- ! >
515- ! Get the parent.
516- ! Returns a [[json_value]] pointer.
517- interface json_get_parent
518- module procedure json_value_get_parent
519- end interface json_get_parent
520- ! *************************************************************************************
521-
522513 ! *************************************************************************************
523514 ! >
524515 ! Add objects to a linked list of [[json_value]]s.
@@ -677,7 +668,7 @@ end subroutine traverse_callback_func
677668 module procedure MAYBEWRAP(json_value_remove_if_present)
678669 end interface
679670 ! *************************************************************************************
680-
671+
681672 ! *************************************************************************************
682673 ! >
683674 ! Allocate a [[json_value]] pointer and make it a double variable.
@@ -840,10 +831,14 @@ end subroutine traverse_callback_func
840831 public :: json_create_object ! allocate a json_value object
841832 public :: json_create_string ! allocate a json_value string
842833 public :: json_destroy ! clear a JSON structure (destructor)
834+ public :: json_clone ! clone a JSON structure (deep copy)
843835 public :: json_failed ! check for error
844836 public :: json_get ! get data from the JSON structure
845837 public :: json_get_child ! get a child of a json_value
846- public :: json_get_parent ! get the parent of a json_value
838+ public :: json_get_parent ! get pointer to json_value parent
839+ public :: json_get_next ! get pointer to json_value next
840+ public :: json_get_previous ! get pointer to json_value previous
841+ public :: json_get_tail ! get pointer to json_value tail
847842 public :: json_info ! get info about a json_value
848843 public :: json_initialize ! to initialize the module
849844 public :: json_parse ! read a JSON file and populate the structure
@@ -944,6 +939,112 @@ end subroutine traverse_callback_func
944939 contains
945940! *****************************************************************************************
946941
942+ ! *****************************************************************************************
943+ ! > author: Jacob Williams
944+ ! date: 10/31/2015
945+ !
946+ ! Create a deep copy of a [[json_value]] linked-list structure.
947+ !
948+ ! # Example
949+ !
950+ ! ```fortran
951+ ! program test
952+ ! use json_module
953+ ! implicit none
954+ ! type(json_value),pointer :: j1, j2
955+ ! call json_initialize()
956+ ! call json_parse('../files/inputs/test1.json',j1)
957+ ! call json_clone(j1,j2) !now have two independent copies
958+ ! call json_destroy(j1) !destroys j1, but j2 remains
959+ ! call json_print(j2,'j2.json')
960+ ! call json_destroy(j2)
961+ ! end program test
962+ ! ```
963+
964+ subroutine json_clone (from ,to )
965+
966+ implicit none
967+
968+ type (json_value),pointer :: from ! ! this is the structure to clone
969+ type (json_value),pointer :: to ! ! the clone is put here
970+ ! ! (it must not already be associated)
971+
972+ ! call the main function:
973+ call json_value_clone_func(from,to )
974+
975+ end subroutine json_clone
976+ ! *****************************************************************************************
977+
978+ ! *****************************************************************************************
979+ ! > author: Jacob Williams
980+ ! date: 10/31/2015
981+ !
982+ ! Recursive deep copy function called by [[json_clone]].
983+ !
984+ ! @note If new data is added to the [[json_value]] type,
985+ ! then this would need to be updated.
986+
987+ recursive subroutine json_value_clone_func (from ,to ,parent ,previous ,next ,children ,tail )
988+
989+ implicit none
990+
991+ type (json_value),pointer :: from ! ! this is the structure to clone
992+ type (json_value),pointer :: to ! ! the clone is put here
993+ ! ! (it must not already be associated)
994+ type (json_value),pointer ,optional :: parent ! ! to%parent
995+ type (json_value),pointer ,optional :: previous ! ! to%previous
996+ type (json_value),pointer ,optional :: next ! ! to%next
997+ type (json_value),pointer ,optional :: children ! ! to%children
998+ logical ,optional :: tail ! ! if "to" is the tail of its parent's children
999+
1000+ nullify(to )
1001+
1002+ if (associated (from)) then
1003+
1004+ allocate (to )
1005+
1006+ ! copy over the data variables:
1007+
1008+ if (allocated (from% name)) allocate (to % name, source= from% name)
1009+ if (allocated (from% dbl_value)) allocate (to % dbl_value,source= from% dbl_value)
1010+ if (allocated (from% log_value)) allocate (to % log_value,source= from% log_value)
1011+ if (allocated (from% str_value)) allocate (to % str_value,source= from% str_value)
1012+ if (allocated (from% int_value)) allocate (to % int_value,source= from% int_value)
1013+ to % var_type = from% var_type
1014+ to % n_children = from% n_children
1015+
1016+ ! allocate and associate the pointers as necessary:
1017+
1018+ if (present (parent)) to % parent = > parent
1019+ if (present (previous)) to % previous = > previous
1020+ if (present (next)) to % next = > next
1021+ if (present (children)) to % children = > children
1022+ if (present (tail)) then
1023+ if (tail) to % parent% tail = > to
1024+ end if
1025+
1026+ if (associated (from% next)) then
1027+ allocate (to % next)
1028+ call json_value_clone_func(from% next,&
1029+ to % next,&
1030+ previous= to ,&
1031+ parent= to % parent,&
1032+ tail= (.not. associated (from% next% next)))
1033+ end if
1034+
1035+ if (associated (from% children)) then
1036+ allocate (to % children)
1037+ call json_value_clone_func(from% children,&
1038+ to % children,&
1039+ parent= to ,&
1040+ tail= (.not. associated (from% children% next)))
1041+ end if
1042+
1043+ end if
1044+
1045+ end subroutine json_value_clone_func
1046+ ! *****************************************************************************************
1047+
9471048! *****************************************************************************************
9481049! > author: Izaak Beekman
9491050! date: 07/23/2015
@@ -954,8 +1055,8 @@ function initialize_json_file(p) result(file_object)
9541055
9551056 implicit none
9561057
957- type (json_value), pointer , optional , intent (in ) :: p ! ! `json_value` object to cast
958- ! ! as a `json_file` object
1058+ type (json_value),pointer ,optional ,intent (in ) :: p ! ! `json_value` object to cast
1059+ ! ! as a `json_file` object
9591060 type (json_file) :: file_object
9601061
9611062 if (present (p)) file_object% p = > p
@@ -3274,20 +3375,73 @@ end function json_count
32743375! Returns a pointer to the parent of a [[json_value]].
32753376! If there is no parent, then a null() pointer is returned.
32763377
3277- subroutine json_value_get_parent (me ,p )
3378+ subroutine json_get_parent (me ,p )
32783379
32793380 implicit none
32803381
32813382 type (json_value),pointer ,intent (in ) :: me ! ! JSON object
3282- type (json_value),pointer :: p ! ! pointer to the parent
3383+ type (json_value),pointer , intent ( out ) :: p ! ! pointer to parent
32833384
3284- if (associated (me% parent)) then
3285- p = > me% parent
3286- else
3287- p = > null ()
3288- end if
3385+ p = > me% parent
3386+
3387+ end subroutine json_get_parent
3388+ ! *****************************************************************************************
3389+
3390+ ! *****************************************************************************************
3391+ ! > author: Jacob Williams
3392+ ! date: 10/31/2015
3393+ !
3394+ ! Returns a pointer to the next of a [[json_value]].
3395+ ! If there is no next, then a null() pointer is returned.
3396+
3397+ subroutine json_get_next (me ,p )
3398+
3399+ implicit none
3400+
3401+ type (json_value),pointer ,intent (in ) :: me ! ! JSON object
3402+ type (json_value),pointer ,intent (out ) :: p ! ! pointer to next
3403+
3404+ p = > me% next
3405+
3406+ end subroutine json_get_next
3407+ ! *****************************************************************************************
3408+
3409+ ! *****************************************************************************************
3410+ ! > author: Jacob Williams
3411+ ! date: 10/31/2015
3412+ !
3413+ ! Returns a pointer to the previous of a [[json_value]].
3414+ ! If there is no previous, then a null() pointer is returned.
3415+
3416+ subroutine json_get_previous (me ,p )
3417+
3418+ implicit none
3419+
3420+ type (json_value),pointer ,intent (in ) :: me ! ! JSON object
3421+ type (json_value),pointer ,intent (out ) :: p ! ! pointer to previous
3422+
3423+ p = > me% previous
3424+
3425+ end subroutine json_get_previous
3426+ ! *****************************************************************************************
3427+
3428+ ! *****************************************************************************************
3429+ ! > author: Jacob Williams
3430+ ! date: 10/31/2015
3431+ !
3432+ ! Returns a pointer to the tail of a [[json_value]].
3433+ ! If there is no tail, then a null() pointer is returned.
3434+
3435+ subroutine json_get_tail (me ,p )
3436+
3437+ implicit none
3438+
3439+ type (json_value),pointer ,intent (in ) :: me ! ! JSON object
3440+ type (json_value),pointer ,intent (out ) :: p ! ! pointer to tail
3441+
3442+ p = > me% tail
32893443
3290- end subroutine json_value_get_parent
3444+ end subroutine json_get_tail
32913445! *****************************************************************************************
32923446
32933447! *****************************************************************************************
0 commit comments