62 implicit none;
private
108 character(:),
allocatable :: chars
111 procedure, pass(lhs),
private :: character_assign_string
112 procedure, pass(rhs),
private :: string_assign_character
113 procedure, pass(lhs),
private :: string_eq_string
114 procedure, pass(lhs),
private :: string_eq_character
115 procedure, pass(rhs),
private :: character_eq_string
116 procedure, pass(dtv),
private :: write_formatted
118 generic,
public ::
assignment(=) => character_assign_string, &
119 string_assign_character
120 generic,
public ::
operator(==) => string_eq_string, &
121 string_eq_character, &
123 generic,
public ::
write(formatted) => write_formatted
131 module procedure :: string_len
139 module procedure :: string_len_trim
147 module procedure :: string_trim
154 interface operator(//)
155 module procedure :: string_concat_string
156 module procedure :: string_concat_character
157 module procedure :: character_concat_string
164 interface operator(.contains.)
165 module procedure :: strings_contain_string
166 module procedure :: strings_contain_character
167 module procedure :: characters_contain_string
168 module procedure :: characters_contain_character
185 subroutine character_assign_string(lhs, rhs)
186 class(
string),
intent(inout) :: lhs
187 character(*),
intent(in) :: rhs
189 if (
allocated(lhs%chars))
deallocate(lhs%chars)
190 allocate(lhs%chars, source=rhs)
208 subroutine string_assign_character(lhs, rhs)
209 character(:),
allocatable,
intent(inout) :: lhs
210 class(
string),
intent(in) :: rhs
230 elemental integer function string_len(this)
result(res)
231 class(
string),
intent(in) :: this
233 if (
allocated(this%chars))
then
234 res =
len(this%chars)
255 pure integer function string_len_trim(this)
result(res)
256 class(
string),
intent(in) :: this
258 if (
allocated(this%chars))
then
270 pure function string_trim(this)
result(res)
271 class(
string),
intent(in) :: this
272 character(:),
allocatable :: res
274 if (
allocated(this%chars))
then
275 res =
trim(this%chars)
287 pure function string_concat_string(lhs, rhs)
result(res)
288 class(
string),
intent(in) :: lhs
289 class(
string),
intent(in) :: rhs
290 character(:),
allocatable :: res
292 if (
allocated(lhs%chars) .and.
allocated(rhs%chars))
then
293 res = lhs%chars // rhs%chars
294 elseif (
allocated(lhs%chars))
then
296 elseif (
allocated(rhs%chars))
then
309 pure function string_concat_character(lhs, rhs)
result(res)
310 class(
string),
intent(in) :: lhs
311 character(*),
intent(in) :: rhs
312 character(:),
allocatable :: res
314 if (
allocated(lhs%chars))
then
315 res = lhs%chars // rhs
327 pure function character_concat_string(lhs, rhs)
result(res)
328 character(*),
intent(in) :: lhs
329 class(
string),
intent(in) :: rhs
330 character(:),
allocatable :: res
332 if (
allocated(rhs%chars))
then
333 res = lhs // rhs%chars
345 elemental function string_eq_string(lhs, rhs)
result(res)
346 class(
string),
intent(in) :: lhs
347 type(
string),
intent(in) :: rhs
350 if (.not.
allocated(lhs%chars))
then
351 res =
allocated(rhs%chars)
353 res = lhs%chars == rhs%chars
363 elemental function string_eq_character(lhs, rhs)
result(res)
364 class(
string),
intent(in) :: lhs
365 character(*),
intent(in) :: rhs
368 if (.not.
allocated(lhs%chars))
then
371 res = lhs%chars == rhs
381 elemental function character_eq_string(lhs, rhs)
result(res)
382 character(*),
intent(in) :: lhs
383 class(
string),
intent(in) :: rhs
386 if (.not.
allocated(rhs%chars))
then
389 res = rhs%chars == lhs
433 subroutine write_formatted(dtv, unit, iotype, v_list, iostat, iomsg)
434 class(
string),
intent(in) :: dtv
435 integer,
intent(in) :: unit
436 character(*),
intent(in) :: iotype
437 integer,
intent(in) :: v_list(:)
438 integer,
intent(out) :: iostat
439 character(*),
intent(inout) :: iomsg
441 if (
allocated(dtv%chars))
then
442 write(unit,
'(A)', iostat=iostat, iomsg=iomsg) dtv%chars
444 write(unit,
'(A)', iostat=iostat, iomsg=iomsg)
''
485 character(*),
intent(in) :: str
486 character(*),
intent(in) :: arg1
487 integer,
intent(out),
optional :: idx
491 i = index(
trim(adjustl(str)),
trim(arg1))
493 if (
present(idx)) idx = i
502 character function head(str)
result(res)
503 character(*),
intent(in) :: str
517 character function tail(str)
result(res)
518 character(*),
intent(in) :: str
536 character(*),
intent(in) :: str1
537 character(*),
intent(in) :: str2
538 character(:),
allocatable :: res
542 n1 =
len(str1); n2 = 1
543 if (
head(str1) ==
'!')
then
553 if (
head(adjustl(str2(n2:))) ==
'&')
then
554 n2 = index(str2,
'&') + 1
558 if (
head(
trim(str2)) ==
'&') n2 = index(str2,
'&') + 1
559 if (
tail(str1(:n1)) ==
'(') n1 = index(str1(:n1),
'(', back=.true.)
562 if (
len(str1) > 0 .and.
len(str2) >= n2)
then
563 if (str1(n1:n1) ==
' ' .and. str2(n2:n2) ==
' ') n2 = n2 + 1
565 res = str1(:n1) // str2(n2:)
583 character(*),
intent(in) :: str
584 character(len_trim(str)) :: res
586 integer :: ilen, ioffset, iquote, iqc, iav, i
589 ioffset = iachar(
'A') - iachar(
'a')
593 iav = iachar(str(i:i))
594 if (iquote == 0 .and. (iav == 34 .or. iav == 39))
then
599 if (iquote == 1 .and. iav == iqc)
then
603 if (iquote == 1) cycle
604 if (iav >= iachar(
'a') .and. iav <= iachar(
'z'))
then
605 res(i:i) = achar(iav + ioffset)
619 integer,
intent(in) :: unit
620 character(*),
intent(in) :: str
625 if (
head(str) /=
'!')
then
631 write(unit,
'(A)') str(n *
chksize + 1:)
641 character(1) function previous(line, pos)
result(res)
642 character(*),
intent(in) :: line
643 integer,
intent(inout) :: pos
647 res =
trim(line(pos:pos))
649 do while (line(pos:pos) ==
' ')
663 logical function strings_contain_string(lhs, rhs)
result(res)
664 type(
string),
intent(in) :: lhs(:)
665 type(
string),
intent(in) :: rhs
671 if (lhs(i) == rhs)
then
684 logical function strings_contain_character(lhs, rhs)
result(res)
685 type(
string),
intent(in) :: lhs(:)
686 character(*),
intent(in) :: rhs
692 if (lhs(i) == rhs)
then
705 logical function characters_contain_character(lhs, rhs)
result(res)
706 character(*),
intent(in) :: lhs(:)
707 character(*),
intent(in) :: rhs
713 if (lhs(i) == rhs)
then
726 logical function characters_contain_string(lhs, rhs)
result(res)
727 character(*),
intent(in) :: lhs(:)
728 type(
string),
intent(in) :: rhs
734 if (lhs(i) == rhs)
then
integer, parameter, public chksize
Maximum chunk size.
character function, public tail(str)
Returns the last non-blank character of a string.
subroutine, public writechk(unit, str)
Write a long line split into chunks of size CHKSIZE with continuation (&).
character(1) function, public previous(line, pos)
Returns the previous non-blank character before position pos (updates pos).
pure character(len_trim(str)) function, public uppercase(str)
Convert string to upper case (respects contents of quotes).
character(:) function, allocatable, public concat(str1, str2)
Smart concatenation that removes continuation markers (&) and handles line-continuation rules.
logical function, public starts_with(str, arg1, idx)
Checks if a string starts with a given prefix Returns .true. if the string str (after trimming leadin...
character function, public head(str)
Returns the first non-blank character of a string.
Return the trimmed length of a string.
Return the length of a string.
Return the trimmed string.
Represents text as a sequence of ASCII code units. The derived type wraps an allocatable character ar...