stringify Function

private pure function stringify(value, separator)

Uses

  • proc~~stringify~~UsesGraph proc~stringify stringify iso_fortran_env iso_fortran_env proc~stringify->iso_fortran_env

Convert one or more values of any intrinsic data types to a character string for pretty printing. If value contains more than one element, the elements will be stringified, delimited by separator, then concatenated. If value contains exactly one element, the element will be stringified without using separator. If value contains zero element or is of unsupported data types, an empty character string is produced. If separator is not supplied, it defaults to ", " (i.e., a comma and a space). (KCW, 2024-02-04)

Arguments

Type IntentOptional Attributes Name
class(*), intent(in) :: value(:)
character(len=*), intent(in), optional :: separator

Return Value character(len=:), allocatable


Called by

proc~~stringify~~CalledByGraph proc~stringify stringify proc~dyn_mpas_check_variable_status mpas_dynamical_core_type%dyn_mpas_check_variable_status proc~dyn_mpas_check_variable_status->proc~stringify proc~dyn_mpas_debug_print mpas_dynamical_core_type%dyn_mpas_debug_print proc~dyn_mpas_check_variable_status->proc~dyn_mpas_debug_print proc~dyn_mpas_debug_print->proc~stringify proc~dyn_mpas_define_scalar mpas_dynamical_core_type%dyn_mpas_define_scalar proc~dyn_mpas_define_scalar->proc~stringify proc~dyn_mpas_define_scalar->proc~dyn_mpas_debug_print proc~dyn_mpas_exchange_halo mpas_dynamical_core_type%dyn_mpas_exchange_halo proc~dyn_mpas_exchange_halo->proc~stringify proc~dyn_mpas_exchange_halo->proc~dyn_mpas_debug_print proc~dyn_mpas_init_phase3 mpas_dynamical_core_type%dyn_mpas_init_phase3 proc~dyn_mpas_init_phase3->proc~stringify proc~dyn_mpas_init_phase3->proc~dyn_mpas_debug_print proc~dyn_mpas_init_phase4 mpas_dynamical_core_type%dyn_mpas_init_phase4 proc~dyn_mpas_init_phase4->proc~stringify proc~dyn_mpas_init_phase4->proc~dyn_mpas_debug_print proc~dyn_mpas_init_stream_with_pool mpas_dynamical_core_type%dyn_mpas_init_stream_with_pool proc~dyn_mpas_init_stream_with_pool->proc~stringify proc~dyn_mpas_init_stream_with_pool->proc~dyn_mpas_check_variable_status proc~dyn_mpas_init_stream_with_pool->proc~dyn_mpas_debug_print none~add_stream_attribute add_stream_attribute proc~dyn_mpas_init_stream_with_pool->none~add_stream_attribute proc~dyn_mpas_read_namelist mpas_dynamical_core_type%dyn_mpas_read_namelist proc~dyn_mpas_read_namelist->proc~stringify proc~dyn_mpas_read_namelist->proc~dyn_mpas_debug_print proc~dyn_mpas_run mpas_dynamical_core_type%dyn_mpas_run proc~dyn_mpas_run->proc~stringify proc~dyn_mpas_run->proc~dyn_mpas_debug_print none~add_stream_attribute_0d add_stream_attribute_0d none~add_stream_attribute_0d->proc~dyn_mpas_debug_print none~add_stream_attribute_1d add_stream_attribute_1d none~add_stream_attribute_1d->proc~dyn_mpas_debug_print none~set_mpas_physics_tendency_rho set_mpas_physics_tendency_rho none~set_mpas_physics_tendency_rho->proc~dyn_mpas_exchange_halo none~set_mpas_physics_tendency_rtheta set_mpas_physics_tendency_rtheta none~set_mpas_physics_tendency_rtheta->proc~dyn_mpas_exchange_halo none~set_mpas_state_rho_base_theta_base set_mpas_state_rho_base_theta_base none~set_mpas_state_rho_base_theta_base->proc~dyn_mpas_exchange_halo none~set_mpas_state_rho_theta set_mpas_state_rho_theta none~set_mpas_state_rho_theta->proc~dyn_mpas_exchange_halo none~set_mpas_state_scalars set_mpas_state_scalars none~set_mpas_state_scalars->proc~dyn_mpas_exchange_halo none~set_mpas_state_w set_mpas_state_w none~set_mpas_state_w->proc~dyn_mpas_exchange_halo proc~dyn_exchange_constituent_states dyn_exchange_constituent_states proc~dyn_exchange_constituent_states->proc~dyn_mpas_exchange_halo proc~dyn_init dyn_init proc~dyn_init->proc~dyn_mpas_define_scalar proc~dyn_init->proc~dyn_mpas_init_phase4 proc~dyn_init->proc~dyn_exchange_constituent_states proc~dyn_mpas_read_write_stream mpas_dynamical_core_type%dyn_mpas_read_write_stream proc~dyn_init->proc~dyn_mpas_read_write_stream proc~set_analytic_initial_condition set_analytic_initial_condition proc~dyn_init->proc~set_analytic_initial_condition proc~dyn_mpas_compute_edge_wind mpas_dynamical_core_type%dyn_mpas_compute_edge_wind proc~dyn_mpas_compute_edge_wind->proc~dyn_mpas_debug_print proc~dyn_mpas_compute_edge_wind->proc~dyn_mpas_exchange_halo proc~dyn_mpas_compute_unit_vector mpas_dynamical_core_type%dyn_mpas_compute_unit_vector proc~dyn_mpas_compute_unit_vector->proc~dyn_mpas_debug_print proc~dyn_mpas_final mpas_dynamical_core_type%dyn_mpas_final proc~dyn_mpas_final->proc~dyn_mpas_debug_print proc~dyn_mpas_get_global_mesh_dimension mpas_dynamical_core_type%dyn_mpas_get_global_mesh_dimension proc~dyn_mpas_get_global_mesh_dimension->proc~dyn_mpas_debug_print proc~dyn_mpas_get_local_mesh_dimension mpas_dynamical_core_type%dyn_mpas_get_local_mesh_dimension proc~dyn_mpas_get_local_mesh_dimension->proc~dyn_mpas_debug_print proc~dyn_mpas_init_phase1 mpas_dynamical_core_type%dyn_mpas_init_phase1 proc~dyn_mpas_init_phase1->proc~dyn_mpas_debug_print proc~dyn_mpas_init_phase2 mpas_dynamical_core_type%dyn_mpas_init_phase2 proc~dyn_mpas_init_phase2->proc~dyn_mpas_debug_print proc~dyn_mpas_read_write_stream->proc~dyn_mpas_debug_print proc~dyn_mpas_read_write_stream->proc~dyn_mpas_exchange_halo proc~dyn_mpas_read_write_stream->proc~dyn_mpas_init_stream_with_pool proc~dyn_readnl dyn_readnl proc~dyn_readnl->proc~dyn_mpas_read_namelist proc~dyn_readnl->proc~dyn_mpas_init_phase1 proc~dyn_readnl->proc~dyn_mpas_init_phase2 proc~dyn_run dyn_run proc~dyn_run->proc~dyn_mpas_run proc~dyn_variable_dump dyn_variable_dump proc~dyn_variable_dump->proc~dyn_mpas_exchange_halo proc~dyn_variable_dump->proc~dyn_mpas_read_write_stream proc~model_grid_init model_grid_init proc~model_grid_init->proc~dyn_mpas_init_phase3 proc~model_grid_init->proc~dyn_mpas_compute_unit_vector proc~model_grid_init->proc~dyn_mpas_read_write_stream proc~dyn_inquire_mesh_dimensions dyn_inquire_mesh_dimensions proc~model_grid_init->proc~dyn_inquire_mesh_dimensions none~add_stream_attribute->none~add_stream_attribute_0d none~add_stream_attribute->none~add_stream_attribute_1d none~set_mpas_physics_tendency_ru set_mpas_physics_tendency_ru none~set_mpas_physics_tendency_ru->proc~dyn_mpas_compute_edge_wind none~set_mpas_state_u set_mpas_state_u none~set_mpas_state_u->proc~dyn_mpas_compute_edge_wind none~set_physics_state_external set_physics_state_external none~set_physics_state_external->proc~dyn_exchange_constituent_states proc~dyn_final dyn_final proc~dyn_final->proc~dyn_variable_dump proc~dyn_inquire_mesh_dimensions->proc~dyn_mpas_get_global_mesh_dimension proc~dyn_inquire_mesh_dimensions->proc~dyn_mpas_get_local_mesh_dimension proc~dynamics_to_physics_coupling dynamics_to_physics_coupling proc~dynamics_to_physics_coupling->proc~dyn_exchange_constituent_states proc~dynamics_to_physics_coupling->none~set_physics_state_external proc~physics_to_dynamics_coupling physics_to_dynamics_coupling proc~physics_to_dynamics_coupling->none~set_mpas_physics_tendency_rho proc~physics_to_dynamics_coupling->none~set_mpas_physics_tendency_rtheta proc~physics_to_dynamics_coupling->proc~dyn_exchange_constituent_states proc~physics_to_dynamics_coupling->none~set_mpas_physics_tendency_ru proc~set_analytic_initial_condition->none~set_mpas_state_rho_base_theta_base proc~set_analytic_initial_condition->none~set_mpas_state_rho_theta proc~set_analytic_initial_condition->none~set_mpas_state_scalars proc~set_analytic_initial_condition->none~set_mpas_state_w proc~set_analytic_initial_condition->none~set_mpas_state_u proc~stepon_run3 stepon_run3 proc~stepon_run3->proc~dyn_run proc~stepon_final stepon_final proc~stepon_final->proc~dyn_final proc~stepon_run2 stepon_run2 proc~stepon_run2->proc~physics_to_dynamics_coupling proc~stepon_timestep_init stepon_timestep_init proc~stepon_timestep_init->proc~dynamics_to_physics_coupling

Variables

Type Visibility Attributes Name Initial
character(len=:), private, allocatable :: buffer
character(len=:), private, allocatable :: delimiter
character(len=:), private, allocatable :: format
integer, private :: i
integer, private :: n
integer, private :: offset
integer, private, parameter :: sizelimit = 1024
character(len=:), private, allocatable :: value_c(:)

Source Code

    pure function stringify(value, separator)
        use, intrinsic :: iso_fortran_env, only: int32, int64, real32, real64

        class(*), intent(in) :: value(:)
        character(*), optional, intent(in) :: separator
        character(:), allocatable :: stringify

        integer, parameter :: sizelimit = 1024

        character(:), allocatable :: buffer, delimiter, format
        character(:), allocatable :: value_c(:)
        integer :: i, n, offset

        if (present(separator)) then
            delimiter = separator
        else
            delimiter = ', '
        end if

        n = min(size(value), sizelimit)

        if (n == 0) then
            stringify = ''

            return
        end if

        select type (value)
            type is (character(*))
                allocate(character(len(value) * n + len(delimiter) * (n - 1)) :: buffer)

                buffer(:) = ''
                offset = 0

                ! Workaround for a bug in GNU Fortran >= 12. This is perhaps the manifestation of GCC Bugzilla Bug 100819.
                ! When a character string array is passed as the actual argument to an unlimited polymorphic dummy argument,
                ! its array index and length parameter are mishandled.
                allocate(character(len(value)) :: value_c(size(value)))

                value_c(:) = value(:)

                do i = 1, n
                    if (len(delimiter) > 0 .and. i > 1) then
                        buffer(offset + 1:offset + len(delimiter)) = delimiter
                        offset = offset + len(delimiter)
                    end if

                    if (len_trim(adjustl(value_c(i))) > 0) then
                        buffer(offset + 1:offset + len_trim(adjustl(value_c(i)))) = trim(adjustl(value_c(i)))
                        offset = offset + len_trim(adjustl(value_c(i)))
                    end if
                end do

                deallocate(value_c)
            type is (integer(int32))
                allocate(character(11 * n + len(delimiter) * (n - 1)) :: buffer)
                allocate(character(17 + len(delimiter) + floor(log10(real(n))) + 1) :: format)

                write(format, '(a, i0, 3a)') '(ss, ', n, '(i0, :, "', delimiter, '"))'
                write(buffer, format) value
            type is (integer(int64))
                allocate(character(20 * n + len(delimiter) * (n - 1)) :: buffer)
                allocate(character(17 + len(delimiter) + floor(log10(real(n))) + 1) :: format)

                write(format, '(a, i0, 3a)') '(ss, ', n, '(i0, :, "', delimiter, '"))'
                write(buffer, format) value
            type is (logical)
                allocate(character(1 * n + len(delimiter) * (n - 1)) :: buffer)
                allocate(character(13 + len(delimiter) + floor(log10(real(n))) + 1) :: format)

                write(format, '(a, i0, 3a)') '(', n, '(l1, :, "', delimiter, '"))'
                write(buffer, format) value
            type is (real(real32))
                allocate(character(13 * n + len(delimiter) * (n - 1)) :: buffer)

                if (maxval(abs(value)) < 1.0e5_real32) then
                    allocate(character(20 + len(delimiter) + floor(log10(real(n))) + 1) :: format)
                    write(format, '(a, i0, 3a)') '(ss, ', n, '(f13.6, :, "', delimiter, '"))'
                else
                    allocate(character(23 + len(delimiter) + floor(log10(real(n))) + 1) :: format)
                    write(format, '(a, i0, 3a)') '(ss, ', n, '(es13.6e2, :, "', delimiter, '"))'
                end if

                write(buffer, format) value
            type is (real(real64))
                allocate(character(13 * n + len(delimiter) * (n - 1)) :: buffer)

                if (maxval(abs(value)) < 1.0e5_real64) then
                    allocate(character(20 + len(delimiter) + floor(log10(real(n))) + 1) :: format)
                    write(format, '(a, i0, 3a)') '(ss, ', n, '(f13.6, :, "', delimiter, '"))'
                else
                    allocate(character(23 + len(delimiter) + floor(log10(real(n))) + 1) :: format)
                    write(format, '(a, i0, 3a)') '(ss, ', n, '(es13.6e2, :, "', delimiter, '"))'
                end if

                write(buffer, format) value
            class default
                stringify = ''

                return
        end select

        stringify = trim(buffer)
    end function stringify