Skip to content

Commit e636f96

Browse files
committed
Refactored the parse_array routine.
-no longer recursive. -added additional error exceptions during parsing if the file is invalid (included a new test case for this). added a new verbose error printing mode.
1 parent a9f690e commit e636f96

File tree

3 files changed

+83
-20
lines changed

3 files changed

+83
-20
lines changed

files/invalid.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"notes": "This is an invalid JSON file, used to test error handling.",
3+
"version": {
4+
"major": 2,
5+
"minor": 0,
6+
"patch": 0,
7+
"revision": 1805
8+
},
9+
"files": [
10+
"..\\path\\to\\files\\file1.txt",
11+
"..\\path\\to\\files\\file2.txt",
12+
"..\\path\\to\\files\\file3.txt"
13+
}

src/json_example.f90

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,45 @@ program json_test
7070
call test_3()
7171
call test_4()
7272
call test_5()
73+
call test_6()
7374

7475
!call memory_leak_test()
7576

7677
contains
7778
!*******************************************************************************************************
7879

80+
81+
!**************************************************************
82+
subroutine test_6()
83+
!**************************************************************
84+
!
85+
! This example tries to read an invalid json file.
86+
!
87+
!**************************************************************
88+
implicit none
89+
90+
type(json_file) :: json
91+
92+
write(*,'(A)') ''
93+
write(*,'(A)') '================================='
94+
write(*,'(A)') ' EXAMPLE 6 : invalid JSON file '
95+
write(*,'(A)') '================================='
96+
write(*,'(A)') ''
97+
98+
! parse the json file:
99+
write(*,'(A)') 'load file...'
100+
call json%load_file(filename = dir//'invalid.json')
101+
if (json_failed()) then
102+
call print_error_message()
103+
end if
104+
105+
! clean up
106+
call json%destroy()
107+
108+
!**************************************************************
109+
end subroutine test_6
110+
!**************************************************************
111+
79112
!**************************************************************
80113
subroutine test_5()
81114
!**************************************************************

src/json_module.f90

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -465,8 +465,9 @@ end subroutine array_callback_func
465465
public :: to_array !
466466

467467
!exception handling [private variables]
468-
logical :: exception_thrown = .false. !the error flag
469-
character(len=:),allocatable :: err_message !the error message
468+
logical :: is_verbose = .false. !if true, all exceptions are immediately printed to console
469+
logical :: exception_thrown = .false. !the error flag
470+
character(len=:),allocatable :: err_message !the error message
470471

471472
! POP/PUSH CHARACTER [private variables]
472473
integer :: char_count = 0
@@ -1030,9 +1031,14 @@ end subroutine get_char_vec_from_json_file
10301031
!
10311032
! SOURCE
10321033

1033-
subroutine json_initialize()
1034+
subroutine json_initialize(verbose)
10341035

10351036
implicit none
1037+
1038+
logical,intent(in),optional :: verbose !mainly useful for debugging (default is false)
1039+
1040+
!optional input (if not present, value remains unchanged):
1041+
if (present(verbose)) is_verbose = verbose
10361042

10371043
!clear any errors from previous runs:
10381044
call json_clear_exceptions()
@@ -1095,7 +1101,13 @@ subroutine throw_exception(msg)
10951101

10961102
exception_thrown = .true.
10971103
err_message = trim(msg)
1098-
1104+
1105+
if (is_verbose) then
1106+
write(*,'(A)') '***********************'
1107+
write(*,'(A)') 'JSON-FORTRAN EXCEPTION: '//trim(msg)
1108+
write(*,'(A)') '***********************'
1109+
end if
1110+
10991111
end subroutine throw_exception
11001112
!*****************************************************************************************
11011113

@@ -4165,11 +4177,11 @@ end subroutine parse_object
41654177
! parse_array
41664178
!
41674179
! DESCRIPTION
4168-
!
4180+
! Core parsing routine.
41694181
!
41704182
! SOURCE
41714183

4172-
recursive subroutine parse_array(unit, array)
4184+
subroutine parse_array(unit, array)
41734185

41744186
implicit none
41754187

@@ -4179,36 +4191,41 @@ recursive subroutine parse_array(unit, array)
41794191
type(json_value), pointer :: element
41804192
logical :: eof
41814193
character(len=1) :: c
4194+
4195+
do
41824196

4183-
if (.not. exception_thrown) then
4184-
nullify(element)
4197+
if (exception_thrown) exit
41854198

41864199
! try to parse an element value
4200+
nullify(element)
41874201
call json_value_create(element)
41884202
call parse_value(unit, element)
4189-
if (exception_thrown) return
4203+
if (exception_thrown) exit
41904204

41914205
! parse value will disassociate an empty array value
4192-
if (associated(element)) then
4193-
call json_value_add(array, element)
4194-
nullify(element) !cleanup
4195-
end if
4206+
if (associated(element)) call json_value_add(array, element)
41964207

41974208
! popped the next character
41984209
c = pop_char(unit, eof = eof, skip_ws = .true.)
41994210

42004211
if (eof) then
4201-
return
4212+
! The file ended before array was finished:
4213+
call throw_exception('Error in parse_array: '//&
4214+
'End of file encountered when parsing an array.')
4215+
exit
42024216
else if (',' == c) then
42034217
! parse the next element
4204-
call parse_array(unit, array)
4205-
if (exception_thrown) return
4218+
cycle
42064219
else if (']' == c) then
42074220
! end of array
4208-
return
4221+
exit
4222+
else
4223+
call throw_exception('Error in parse_array: '//&
4224+
'Unexpected character encountered when parsing array.')
4225+
exit
42094226
end if
4210-
4211-
end if
4227+
4228+
end do
42124229

42134230
end subroutine parse_array
42144231
!*****************************************************************************************
@@ -4320,7 +4337,7 @@ end subroutine parse_string
43204337
! parse_for_chars
43214338
!
43224339
! DESCRIPTION
4323-
!
4340+
! Core parsing routine.
43244341
!
43254342
! SOURCE
43264343

0 commit comments

Comments
 (0)