read_delimited Subroutine

private subroutine read_delimited(dtv, unit, delim, iostat, iomsg)

Read a delimited string from a unit connected for formatted input.

If the closing delimiter is followed by end of record, then we return end of record.

Type Bound

string

Arguments

Type IntentOptional Attributes Name
class(string), intent(out) :: dtv

The string.

integer, intent(in) :: unit

Logical unit.

character(kind=CK, len=1), intent(in) :: delim

String delimiter.

integer, intent(out) :: iostat

IO status code.

character(kind=CK, len=*), intent(inout) :: iomsg

IO status message.


Called by

proc~~read_delimited~~CalledByGraph proc~read_delimited stringifor_string_t::string%read_delimited proc~read_formatted stringifor_string_t::string%read_formatted proc~read_formatted->proc~read_delimited

Contents

Source Code


Source Code

   subroutine read_delimited(dtv, unit, delim, iostat, iomsg)
   !< Read a delimited string from a unit connected for formatted input.
   !<
   !< If the closing delimiter is followed by end of record, then we return end of record.
   !<
   !< @note This does not need a doctest, it being tested by [[string::read_formatted]].
   class(string),             intent(out)   :: dtv       !< The string.
   integer,                   intent(in)    :: unit      !< Logical unit.
   character(kind=CK, len=1), intent(in)    :: delim     !< String delimiter.
   integer,                   intent(out)   :: iostat    !< IO status code.
   character(kind=CK, len=*), intent(inout) :: iomsg     !< IO status message.
   character(kind=CK, len=1)                :: ch        !< A character read.
   logical                                  :: was_delim !< Indicates that the last character read was a delimiter.

   was_delim = .false.
   dtv%raw = ''
   do
      read(unit, "(A)", iostat=iostat, iomsg=iomsg) ch
      if (is_iostat_eor(iostat)) then
         if (was_delim) then
           ! end of delimited string followed by end of record is end of the string. Pass back the
           ! end of record condition to the caller
           return
         else
           ! end of record without terminating delimiter - move along
           cycle
         endif
      elseif (iostat /= 0) THEN
        return
      endif
      if (ch == delim) then
         if (was_delim) then
            ! doubled delimiter is one delimiter in the value
            dtv%raw = dtv%raw // ch
            was_delim = .false.
         else
            ! need to test next character to see what is happening
            was_delim = .true.
         endif
      elseif (was_delim) then
         ! the previous character was actually the delimiter for the end of the string. Put back this character
         read(unit, "(TL1)", iostat=iostat, iomsg=iomsg)
         return
      else
         dtv%raw = dtv%raw // ch
      endif
   enddo
   endsubroutine read_delimited