Skip to content

Additional error check after parsing is done #370

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions files/inputs/invalid4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"a": "blah",
"b": 2
}






,
46 changes: 42 additions & 4 deletions src/json_value_module.F90
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,7 @@ module json_value_module
procedure :: json_value_print
procedure :: string_to_int
procedure :: string_to_dble
procedure :: parse_end => json_parse_end
procedure :: parse_value
procedure :: parse_number
procedure :: parse_string
Expand Down Expand Up @@ -8708,7 +8709,7 @@ subroutine json_parse_file(json, file, p, unit)
logical(LK) :: has_duplicate !! if checking for duplicate keys
character(kind=CK,len=:),allocatable :: path !! path to any duplicate key

!clear any exceptions and initialize:
! clear any exceptions and initialize:
call json%initialize()

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

iunit = unit

!check to see if the file is already open
! check to see if the file is already open
! if it is, then use it, otherwise open the file with the name given.
inquire(unit=iunit, opened=is_open, iostat=istat)
if (istat==0 .and. .not. is_open) then
Expand All @@ -8734,7 +8735,7 @@ subroutine json_parse_file(json, file, p, unit)
iostat = istat &
FILE_ENCODING )
else
!if the file is already open, then we need to make sure
! if the file is already open, then we need to make sure
! that it is open with the correct form/access/etc...
end if

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

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

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

!clear any exceptions and initialize:
! clear any exceptions and initialize:
call json%initialize()

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

! parse as a value
call json%parse_value(unit=iunit, str=str, value=p)
call json%parse_end(unit=iunit, str=str)

if (json%exception_thrown) then
call json%annotate_invalid_json(iunit,str)
Expand All @@ -8842,6 +8845,41 @@ subroutine json_parse_string(json, p, str)
end subroutine json_parse_string
!*****************************************************************************************

!*****************************************************************************************
!>
! An error checking routine to call after a file (or string) has been parsed.
! It will throw an exception if there are any other non-whitespace characters
! in the file.

subroutine json_parse_end(json, unit, str)

implicit none

class(json_core),intent(inout) :: json
integer(IK),intent(in) :: unit !! file unit number
character(kind=CK,len=*),intent(in) :: str !! string containing JSON
!! data (only used if `unit=0`)

logical(LK) :: eof !! end-of-file flag
character(kind=CK,len=1) :: c !! character read from file
!! (or string) by [[pop_char]]

! first check for exceptions:
if (json%exception_thrown) return

! pop the next non whitespace character off the file
call json%pop_char(unit, str=str, eof=eof, skip_ws=.true., &
skip_comments=json%allow_comments, popped=c)

if (.not. eof) then
call json%throw_exception('Error in json_parse_end:'//&
' Unexpected character found after parsing value. "'//&
c//'"')
end if

end subroutine json_parse_end
!*****************************************************************************************

!*****************************************************************************************
!>
! Alternate version of [[json_parse_string]], where `str` is kind=CDK.
Expand Down
22 changes: 16 additions & 6 deletions src/tests/jf_test_06.F90
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
! Module for the sixth unit test.
!
!# HISTORY
! * Izaak Beekman : 2/18/2015 : Created (refactoried original json_example.f90 file)
! * Izaak Beekman : 2/18/2015 : Created (refactored original json_example.f90 file)

module jf_test_6_mod

Expand Down Expand Up @@ -34,9 +34,13 @@ subroutine test_6(error_cnt)
character(kind=CK,len=:),allocatable :: expected_error_msg
logical(LK) :: status_ok

character(len=*),dimension(3),parameter :: files = ['invalid.json ',&
character(len=*),dimension(5),parameter :: files = ['invalid.json ',&
'invalid2.json',&
'invalid3.json']
'invalid3.json',&
'invalid4.json',&
' ']

character(len=*),parameter :: invalid_str = '{"a":1} "b": 2}' !! invalid JSON string

error_cnt = 0
call json%initialize()
Expand All @@ -55,9 +59,15 @@ subroutine test_6(error_cnt)

! parse the json file:
write(error_unit,'(A)') ''
write(error_unit,'(A)') 'load file: '//trim(files(i))
write(error_unit,'(A)') ''
call json%load_file(filename = dir//trim(files(i)))
if (files(i)=='') then
write(error_unit,'(A)') 'load string: '//invalid_str
write(error_unit,'(A)') ''
call json%load_from_string(str = invalid_str)
else
write(error_unit,'(A)') 'load file: '//trim(files(i))
write(error_unit,'(A)') ''
call json%load_file(filename = dir//trim(files(i)))
end if
if (json%failed()) then

if (i==1) then
Expand Down