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.

Type Bound

json_core

Arguments

Type IntentOptional Attributes Name
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 json_value_module::json_core%annotate_invalid_json proc~get_current_line_from_file_sequential json_value_module::json_core%get_current_line_from_file_sequential proc~annotate_invalid_json->proc~get_current_line_from_file_sequential proc~get_current_line_from_file_stream json_value_module::json_core%get_current_line_from_file_stream proc~annotate_invalid_json->proc~get_current_line_from_file_stream proc~integer_to_string json_string_utilities::integer_to_string proc~annotate_invalid_json->proc~integer_to_string

Called by

proc~~annotate_invalid_json~~CalledByGraph proc~annotate_invalid_json json_value_module::json_core%annotate_invalid_json proc~json_parse_file json_value_module::json_core%json_parse_file proc~json_parse_file->proc~annotate_invalid_json proc~json_parse_string json_value_module::json_core%json_parse_string proc~json_parse_string->proc~annotate_invalid_json none~deserialize json_value_module::json_core%deserialize none~deserialize->proc~json_parse_string proc~wrap_json_parse_string json_value_module::json_core%wrap_json_parse_string none~deserialize->proc~wrap_json_parse_string none~load json_value_module::json_core%load none~load->proc~json_parse_file proc~json_file_load json_file_module::json_file%json_file_load proc~json_file_load->none~load proc~json_file_load_from_string json_file_module::json_file%json_file_load_from_string proc~json_file_load_from_string->none~deserialize proc~wrap_json_parse_string->none~deserialize none~deserialize~2 json_file_module::json_file%deserialize none~deserialize~2->proc~json_file_load_from_string proc~wrap_json_file_load_from_string json_file_module::json_file%wrap_json_file_load_from_string none~deserialize~2->proc~wrap_json_file_load_from_string proc~assign_string_to_json_file json_file_module::json_file%assign_string_to_json_file proc~assign_string_to_json_file->none~deserialize~2 proc~initialize_json_file_from_string json_file_module::initialize_json_file_from_string proc~initialize_json_file_from_string->none~deserialize~2 proc~initialize_json_file_from_string_v2 json_file_module::initialize_json_file_from_string_v2 proc~initialize_json_file_from_string_v2->none~deserialize~2 proc~wrap_json_file_load_from_string->none~deserialize~2 interface~json_file json_file_module::json_file interface~json_file->proc~initialize_json_file_from_string interface~json_file->proc~initialize_json_file_from_string_v2 proc~wrap_initialize_json_file_from_string json_file_module::wrap_initialize_json_file_from_string interface~json_file->proc~wrap_initialize_json_file_from_string proc~wrap_initialize_json_file_from_string_v2 json_file_module::wrap_initialize_json_file_from_string_v2 interface~json_file->proc~wrap_initialize_json_file_from_string_v2 proc~wrap_assign_string_to_json_file json_file_module::json_file%wrap_assign_string_to_json_file proc~wrap_assign_string_to_json_file->proc~assign_string_to_json_file proc~wrap_initialize_json_file_from_string->proc~initialize_json_file_from_string proc~wrap_initialize_json_file_from_string_v2->proc~initialize_json_file_from_string_v2

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