Skip to content

strings: join, to_c_char #936

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 16 commits into from
Feb 17, 2025
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
add join, to_c_string
  • Loading branch information
perazz committed Feb 11, 2025
commit 5ee6bbbea907f9e850d2230d48d914aac6e9dcbc
95 changes: 93 additions & 2 deletions src/stdlib_strings.fypp
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,18 @@
!> The specification of this module is available [here](../page/specs/stdlib_strings.html).
module stdlib_strings
use stdlib_ascii, only: whitespace
use stdlib_string_type, only: string_type, char, verify, repeat, len
use stdlib_string_type, only: string_type, char, verify, repeat, len, len_trim, move
use stdlib_optval, only: optval
use stdlib_kinds, only: sp, dp, xdp, qp, int8, int16, int32, int64, lk, c_bool
use iso_c_binding, only: c_char, c_null_char
implicit none
private

public :: to_string
public :: to_c_string
public :: strip, chomp
public :: starts_with, ends_with
public :: slice, find, replace_all, padl, padr, count, zfill
public :: slice, find, replace_all, padl, padr, count, zfill, join

!> Version: experimental
!>
Expand Down Expand Up @@ -164,6 +166,17 @@ module stdlib_strings
module procedure :: zfill_char
end interface zfill

!> Version: experimental
!>
!> Joins an array of strings into a single string.
!> The chunks are separated with a space, or an optional user-defined separator.
!> [Specifications](../page/specs/stdlib_strings.html#join)
interface join
module procedure :: join_string
module procedure :: join_char
end interface join


contains


Expand Down Expand Up @@ -943,5 +956,83 @@ contains

end function zfill_char

!> Convert a Fortran character string to a C character array
!>
!> Version: experimental
pure function to_c_string(value) result(cstr)
character(len=*), intent(in) :: value
character(kind=c_char) :: cstr(len(value)+1)
integer :: i
do concurrent (i=1:len(value))
cstr(i) = value(i:i)
end do
cstr(len(value)+1) = c_null_char
end function to_c_string

!> Joins a list of strings with a separator (default: space).
!> Returns a new string
pure function join_string(strings, separator) result(cmd)
type(string_type), intent(in) :: strings(:)
character(len=*), intent(in), optional :: separator
type(string_type) :: cmd
integer :: ltot, i, lt, pos
character(len=:), allocatable :: sep,cmd_char
! Determine separator: use user-provided separator or default space
if (present(separator)) then
sep = separator
else
sep = ' '
end if
! Calculate the total length required, including separators
ltot = sum(len_trim(strings)) + (size(strings) - 1) * len(sep)
allocate(character(len=ltot) :: cmd_char)

! Concatenate strings with separator
pos = 0
do i = 1, size(strings)
lt = len_trim(strings(i))
cmd_char(pos+1:pos+lt) = char(strings(i),1,lt)
pos = pos + lt
if (i < size(strings)) then
cmd_char(pos+1:pos+len(sep)) = sep
pos = pos + len(sep)
end if
end do

call move(from=cmd_char,to=cmd)

end function join_string

!> Joins a list of strings with a separator (default: space).
!> Returns a new string
pure function join_char(strings, separator) result(cmd)
character(*), intent(in) :: strings(:)
character(len=*), intent(in), optional :: separator
character(len=:), allocatable :: cmd
integer :: ltot, i, lt, pos
character(len=:), allocatable :: sep
! Determine separator: use user-provided separator or default space
if (present(separator)) then
sep = separator
else
sep = ' '
end if
! Calculate the total length required, including separators
ltot = sum(len_trim(strings)) + (size(strings) - 1) * len(sep)
allocate(character(len=ltot) :: cmd)

cmd = repeat(' ',ltot)
! Concatenate strings with separator
pos = 0
do i = 1, size(strings)
lt = len_trim(strings(i))
cmd(pos+1:pos+lt) = strings(i)(1:lt)
pos = pos + lt
if (i < size(strings)) then
cmd(pos+1:pos+len(sep)) = sep
pos = pos + len(sep)
end if
end do
end function join_char

end module stdlib_strings