Skip to content
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
6 changes: 3 additions & 3 deletions .github/workflows/fortran_unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ jobs:
- name: Build cam-sima
run: |
cmake \
-DCMAKE_PREFIX_PATH=/home/runner/work/CAM-SIMA/CAM-SIMA/pFUnit/build/installed \
-DCMAKE_PREFIX_PATH=$GITHUB_WORKSPACE/pFUnit/build/installed \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great find!

-DCAM_SIMA_ENABLE_CODE_COVERAGE=ON \
-B./build \
-S./test/unit/fortran
cd build
make

- name: Run fortran unit tests
run: |
cd build && ctest -V --output-on-failure --output-junit test_results.xml
Expand All @@ -54,7 +54,7 @@ jobs:
name: unit-test-results-${{ env.FC }}
path: build/test_results.xml

- name: Setup GCov
- name: Setup Gcov
run: |
python3 -m venv venv
source venv/bin/activate
Expand Down
23 changes: 17 additions & 6 deletions src/core_utils/string_core_utils.F90
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ end function core_int_seconds_to_hhmmss
!> 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).
!> If `separator` is not supplied, it defaults to ", " (i.e., a comma and a space).
!> (KCW, 2024-02-04)
pure function core_stringify(value, separator)
use, intrinsic :: iso_fortran_env, only: int32, int64, real32, real64
Expand All @@ -75,6 +75,7 @@ pure function core_stringify(value, separator)
integer, parameter :: sizelimit = 1024

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

if (present(separator)) then
Expand All @@ -87,6 +88,7 @@ pure function core_stringify(value, separator)

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

return
end if

Expand All @@ -97,17 +99,26 @@ pure function core_stringify(value, separator)
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(i))) > 0) then
buffer(offset + 1:offset + len_trim(adjustl(value(i)))) = trim(adjustl(value(i)))
offset = offset + len_trim(adjustl(value(i)))
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)
Expand Down Expand Up @@ -151,12 +162,12 @@ pure function core_stringify(value, separator)

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

return
end select

core_stringify = trim(buffer)

end function core_stringify

end module string_core_utils
18 changes: 14 additions & 4 deletions src/dynamics/mpas/driver/dyn_mpas_subdriver.F90
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ end subroutine dyn_mpas_debug_print
!> 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).
!> If `separator` is not supplied, it defaults to ", " (i.e., a comma and a space).
!> (KCW, 2024-02-04)
pure function stringify(value, separator)
use, intrinsic :: iso_fortran_env, only: int32, int64, real32, real64
Expand All @@ -347,6 +347,7 @@ pure function stringify(value, separator)
integer, parameter :: sizelimit = 1024

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

if (present(separator)) then
Expand All @@ -370,17 +371,26 @@ pure function stringify(value, separator)
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(i))) > 0) then
buffer(offset + 1:offset + len_trim(adjustl(value(i)))) = trim(adjustl(value(i)))
offset = offset + len_trim(adjustl(value(i)))
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)
Expand Down
Loading