annotate_invalid_json Subroutine

private subroutine annotate_invalid_json(json, iunit, str)

Generate a warning message if there was an error parsing a JSON file or string.

Arguments

TypeIntentOptionalAttributesName
class(json_core), intent(inout) :: json
integer(kind=IK), intent(in) :: iunit

file unit number

character(kind=CK,len=*), intent(in) :: str

string with JSON data


Calls

proc~~annotate_invalid_json~~CallsGraph proc~annotate_invalid_json annotate_invalid_json proc~integer_to_string integer_to_string proc~annotate_invalid_json->proc~integer_to_string

Contents

Source Code


Source Code

    subroutine annotate_invalid_json(json,iunit,str)

    implicit none

    class(json_core),intent(inout)      :: json
    integer(IK),intent(in)              :: iunit !! file unit number
    character(kind=CK,len=*),intent(in) :: str   !! string with JSON data

    character(kind=CK,len=:),allocatable :: line      !! line containing the error
    character(kind=CK,len=:),allocatable :: arrow_str !! arrow string that points
                                                      !! to the current character
    character(kind=CK,len=max_integer_str_len) :: line_str !! current line number string
    character(kind=CK,len=max_integer_str_len) :: char_str !! current character count string
    integer(IK) :: i          !! line number counter
    integer(IK) :: i_nl_prev  !! index of previous newline character
    integer(IK) :: i_nl       !! index of current newline character

    ! If there was an error reading the file, then
    ! print the line where the error occurred:
    if (json%exception_thrown) then

        !the counters for the current line and the last character read:
        call integer_to_string(json%line_count, int_fmt, line_str)
        call integer_to_string(json%char_count, int_fmt, char_str)

        !draw the arrow string that points to the current character:
        arrow_str = repeat('-',max( 0_IK, json%char_count - 1_IK) )//'^'

        if (json%line_count>0 .and. json%char_count>0) then

            if (iunit/=0) then

                if (use_unformatted_stream) then
                    call json%get_current_line_from_file_stream(iunit,line)
                else
                    call json%get_current_line_from_file_sequential(iunit,line)
                end if

            else

                !get the current line from the string:
                ! [this is done by counting the newline characters]
                i_nl_prev = 0  !index of previous newline character
                i_nl = 2  !just in case line_count = 0
                do i=1,json%line_count
                    i_nl = index(str(i_nl_prev+1:),newline)
                    if (i_nl==0) then   !last line - no newline character
                        i_nl = len(str)+1
                        exit
                    end if
                    i_nl = i_nl + i_nl_prev   !index of current newline character
                    i_nl_prev = i_nl          !update for next iteration
                end do
                line = str(i_nl_prev+1 : i_nl-1)  !extract current line

            end if

        else
            !in this case, it was an empty line or file
            line = CK_''
        end if

        ! add a newline for the error display if necessary:
        line = trim(line)
        if (len(line)>0) then
            i = len(line)
            if (line(i:i)/=newline) line = line//newline
        else
            line = line//newline
        end if

        !create the error message:
        if (allocated(json%err_message)) then
            json%err_message = json%err_message//newline
        else
            json%err_message = ''
        end if
        json%err_message = json%err_message//&
                           'line: '//trim(adjustl(line_str))//', '//&
                           'character: '//trim(adjustl(char_str))//newline//&
                           line//arrow_str

        if (allocated(line)) deallocate(line)

    end if

    end subroutine annotate_invalid_json