Skip to content

Commit 765daf2

Browse files
Merge pull request #370 from jacobwilliams/369-verify-parse-end
Additional error check after parsing is done
2 parents 0168c99 + 28babb8 commit 765daf2

File tree

3 files changed

+69
-10
lines changed

3 files changed

+69
-10
lines changed

files/inputs/invalid4.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"a": "blah",
3+
"b": 2
4+
}
5+
6+
7+
8+
9+
10+
11+
,

src/json_value_module.F90

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,7 @@ module json_value_module
726726
procedure :: json_value_print
727727
procedure :: string_to_int
728728
procedure :: string_to_dble
729+
procedure :: parse_end => json_parse_end
729730
procedure :: parse_value
730731
procedure :: parse_number
731732
procedure :: parse_string
@@ -8708,7 +8709,7 @@ subroutine json_parse_file(json, file, p, unit)
87088709
logical(LK) :: has_duplicate !! if checking for duplicate keys
87098710
character(kind=CK,len=:),allocatable :: path !! path to any duplicate key
87108711

8711-
!clear any exceptions and initialize:
8712+
! clear any exceptions and initialize:
87128713
call json%initialize()
87138714

87148715
if ( present(unit) ) then
@@ -8720,7 +8721,7 @@ subroutine json_parse_file(json, file, p, unit)
87208721

87218722
iunit = unit
87228723

8723-
!check to see if the file is already open
8724+
! check to see if the file is already open
87248725
! if it is, then use it, otherwise open the file with the name given.
87258726
inquire(unit=iunit, opened=is_open, iostat=istat)
87268727
if (istat==0 .and. .not. is_open) then
@@ -8734,7 +8735,7 @@ subroutine json_parse_file(json, file, p, unit)
87348735
iostat = istat &
87358736
FILE_ENCODING )
87368737
else
8737-
!if the file is already open, then we need to make sure
8738+
! if the file is already open, then we need to make sure
87388739
! that it is open with the correct form/access/etc...
87398740
end if
87408741

@@ -8763,6 +8764,7 @@ subroutine json_parse_file(json, file, p, unit)
87638764

87648765
! parse as a value
87658766
call json%parse_value(unit=iunit, str=CK_'', value=p)
8767+
call json%parse_end(unit=iunit, str=CK_'')
87668768

87678769
! check for errors:
87688770
if (json%exception_thrown) then
@@ -8812,7 +8814,7 @@ subroutine json_parse_string(json, p, str)
88128814
logical(LK) :: has_duplicate !! if checking for duplicate keys
88138815
character(kind=CK,len=:),allocatable :: path !! path to any duplicate key
88148816

8815-
!clear any exceptions and initialize:
8817+
! clear any exceptions and initialize:
88168818
call json%initialize()
88178819

88188820
! create the value and associate the pointer
@@ -8824,6 +8826,7 @@ subroutine json_parse_string(json, p, str)
88248826

88258827
! parse as a value
88268828
call json%parse_value(unit=iunit, str=str, value=p)
8829+
call json%parse_end(unit=iunit, str=str)
88278830

88288831
if (json%exception_thrown) then
88298832
call json%annotate_invalid_json(iunit,str)
@@ -8842,6 +8845,41 @@ subroutine json_parse_string(json, p, str)
88428845
end subroutine json_parse_string
88438846
!*****************************************************************************************
88448847

8848+
!*****************************************************************************************
8849+
!>
8850+
! An error checking routine to call after a file (or string) has been parsed.
8851+
! It will throw an exception if there are any other non-whitespace characters
8852+
! in the file.
8853+
8854+
subroutine json_parse_end(json, unit, str)
8855+
8856+
implicit none
8857+
8858+
class(json_core),intent(inout) :: json
8859+
integer(IK),intent(in) :: unit !! file unit number
8860+
character(kind=CK,len=*),intent(in) :: str !! string containing JSON
8861+
!! data (only used if `unit=0`)
8862+
8863+
logical(LK) :: eof !! end-of-file flag
8864+
character(kind=CK,len=1) :: c !! character read from file
8865+
!! (or string) by [[pop_char]]
8866+
8867+
! first check for exceptions:
8868+
if (json%exception_thrown) return
8869+
8870+
! pop the next non whitespace character off the file
8871+
call json%pop_char(unit, str=str, eof=eof, skip_ws=.true., &
8872+
skip_comments=json%allow_comments, popped=c)
8873+
8874+
if (.not. eof) then
8875+
call json%throw_exception('Error in json_parse_end:'//&
8876+
' Unexpected character found after parsing value. "'//&
8877+
c//'"')
8878+
end if
8879+
8880+
end subroutine json_parse_end
8881+
!*****************************************************************************************
8882+
88458883
!*****************************************************************************************
88468884
!>
88478885
! Alternate version of [[json_parse_string]], where `str` is kind=CDK.

src/tests/jf_test_06.F90

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
! Module for the sixth unit test.
44
!
55
!# HISTORY
6-
! * Izaak Beekman : 2/18/2015 : Created (refactoried original json_example.f90 file)
6+
! * Izaak Beekman : 2/18/2015 : Created (refactored original json_example.f90 file)
77

88
module jf_test_6_mod
99

@@ -34,9 +34,13 @@ subroutine test_6(error_cnt)
3434
character(kind=CK,len=:),allocatable :: expected_error_msg
3535
logical(LK) :: status_ok
3636

37-
character(len=*),dimension(3),parameter :: files = ['invalid.json ',&
37+
character(len=*),dimension(5),parameter :: files = ['invalid.json ',&
3838
'invalid2.json',&
39-
'invalid3.json']
39+
'invalid3.json',&
40+
'invalid4.json',&
41+
' ']
42+
43+
character(len=*),parameter :: invalid_str = '{"a":1} "b": 2}' !! invalid JSON string
4044

4145
error_cnt = 0
4246
call json%initialize()
@@ -55,9 +59,15 @@ subroutine test_6(error_cnt)
5559

5660
! parse the json file:
5761
write(error_unit,'(A)') ''
58-
write(error_unit,'(A)') 'load file: '//trim(files(i))
59-
write(error_unit,'(A)') ''
60-
call json%load_file(filename = dir//trim(files(i)))
62+
if (files(i)=='') then
63+
write(error_unit,'(A)') 'load string: '//invalid_str
64+
write(error_unit,'(A)') ''
65+
call json%load_from_string(str = invalid_str)
66+
else
67+
write(error_unit,'(A)') 'load file: '//trim(files(i))
68+
write(error_unit,'(A)') ''
69+
call json%load_file(filename = dir//trim(files(i)))
70+
end if
6171
if (json%failed()) then
6272

6373
if (i==1) then

0 commit comments

Comments
 (0)