Skip to content

Commit 8212d59

Browse files
committed
bug fix in json_value_remove
The parent and previous pointers should also be nullified when removing from an array. Fixes #477
1 parent 690a8bd commit 8212d59

File tree

2 files changed

+152
-2
lines changed

2 files changed

+152
-2
lines changed

src/json_value_module.F90

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2340,6 +2340,7 @@ end subroutine json_value_destroy
23402340
!
23412341
!### History
23422342
! * Jacob Williams : 12/28/2014 : added destroy optional argument.
2343+
! * Jacob Williams : 12/04/2020 : bug fix.
23432344

23442345
subroutine json_value_remove(json,p,destroy)
23452346

@@ -2374,9 +2375,7 @@ subroutine json_value_remove(json,p,destroy)
23742375
if (associated(p%next)) then
23752376

23762377
!there are later items in the list:
2377-
23782378
next => p%next
2379-
nullify(p%next)
23802379

23812380
if (associated(p%previous)) then
23822381
!there are earlier items in the list
@@ -2404,6 +2403,11 @@ subroutine json_value_remove(json,p,destroy)
24042403

24052404
end if
24062405

2406+
! nullify all pointers to original structure:
2407+
nullify(p%next)
2408+
nullify(p%previous)
2409+
nullify(p%parent)
2410+
24072411
parent%n_children = parent%n_children - 1
24082412

24092413
end if

src/tests/jf_test_47.F90

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
!*****************************************************************************************
2+
!>
3+
! Module for the 47th unit test
4+
5+
module jf_test_47_mod
6+
7+
use json_module, CK => json_CK, IK => json_IK, RK => json_RK, LK => json_LK
8+
use, intrinsic :: iso_fortran_env , only: error_unit, output_unit
9+
10+
implicit none
11+
12+
private
13+
public :: test_47
14+
15+
contains
16+
17+
subroutine test_47(error_cnt)
18+
19+
!! testing of `remove`.
20+
21+
implicit none
22+
23+
integer,intent(out) :: error_cnt !! error counter
24+
25+
character(kind=CK,len=*), parameter :: STR = CK_'&
26+
&{&
27+
& "object1": {&
28+
& "a": 1,&
29+
& "b": 2,&
30+
& "move1": 3,&
31+
& "move2": 4,&
32+
& "e": 5 &
33+
& },&
34+
& "object2": {&
35+
& "f": 10,&
36+
& "g": 11,&
37+
& "h": 12,&
38+
& "i": 13,&
39+
& "j": 14 &
40+
& }&
41+
&}'
42+
43+
character(kind=CK,len=:), allocatable :: errtxt
44+
type(json_core) :: json
45+
type(json_value), pointer :: inp, p, p2
46+
logical(LK) :: found, status_ok
47+
integer(IK) :: ival
48+
49+
write(error_unit,'(A)') ''
50+
write(error_unit,'(A)') '================================='
51+
write(error_unit,'(A)') ' TEST 47'
52+
write(error_unit,'(A)') '================================='
53+
write(error_unit,'(A)') ''
54+
55+
call json%deserialize(inp, STR)
56+
call json%check_for_errors(status_ok, errtxt)
57+
if (.not. status_ok) then
58+
write(error_unit,'(A)') errtxt
59+
error_cnt = error_cnt + 1
60+
else
61+
call json%print(inp)
62+
write(error_unit,'(A)') ''
63+
write(error_unit,'(A)') 'Move object1.move1 to object2 [clone]...'
64+
call json%get(inp, 'object1.move1', p, found)
65+
if (found) then
66+
call json%clone(p, p2)
67+
call json%remove(p, .true.)
68+
call json%add_by_path(inp, 'object2.move1', p2)
69+
end if
70+
write(error_unit,'(A)') ''
71+
call json%print(inp)
72+
write(error_unit,'(A)') ''
73+
call json%get(inp, 'object2.move1', ival, found)
74+
if (.not. found) then
75+
write(error_unit,'(A)') 'Error moving move1'
76+
error_cnt = error_cnt + 1
77+
else
78+
if (ival==3_IK) then
79+
write(error_unit,'(A)') '...Success'
80+
else
81+
write(error_unit,'(A,1X,I5)') 'Invalid move1 value: ', ival
82+
error_cnt = error_cnt + 1
83+
end if
84+
end if
85+
86+
write(error_unit,'(A)') ''
87+
write(error_unit,'(A)') 'Move object1.move2 to object2...'
88+
89+
call json%get(inp, 'object1.move2', p, found)
90+
if (found) then
91+
call json%remove(p, .false.)
92+
call json%add_by_path(inp, 'object2.move2', p)
93+
end if
94+
write(error_unit,'(A)') ''
95+
call json%print(inp)
96+
write(error_unit,'(A)') ''
97+
call json%get(inp, 'object2.move2', ival, found)
98+
if (.not. found) then
99+
write(error_unit,'(A)') 'Error moving move2'
100+
error_cnt = error_cnt + 1
101+
else
102+
if (ival==4_IK) then
103+
write(error_unit,'(A)') '...Success'
104+
else
105+
write(error_unit,'(A,1X,I5)') 'Invalid move2 value: ', ival
106+
error_cnt = error_cnt + 1
107+
end if
108+
end if
109+
110+
call json%check_for_errors(status_ok, errtxt)
111+
if (.not. status_ok) then
112+
write(error_unit,'(A)') errtxt
113+
error_cnt = error_cnt + 1
114+
end if
115+
116+
end if
117+
118+
write(error_unit,'(A)') ''
119+
if (error_cnt==0) then
120+
write(error_unit,'(A)') 'Success!'
121+
else
122+
write(error_unit,'(A)') 'Failed!'
123+
end if
124+
write(error_unit,'(A)') ''
125+
126+
end subroutine test_47
127+
128+
end module jf_test_47_mod
129+
!*****************************************************************************************
130+
131+
#ifndef INTEGRATED_TESTS
132+
!*****************************************************************************************
133+
program jf_test_47
134+
135+
!! 47th unit test.
136+
137+
use jf_test_47_mod , only: test_47
138+
implicit none
139+
integer :: n_errors
140+
n_errors = 0
141+
call test_47(n_errors)
142+
if (n_errors /= 0) stop 1
143+
144+
end program jf_test_47
145+
!*****************************************************************************************
146+
#endif

0 commit comments

Comments
 (0)