read_undelimited Subroutine

private subroutine read_undelimited(dtv, unit, terminators, iostat, iomsg)

Arguments

TypeIntentOptionalAttributesName
class(string), intent(inout) :: dtv
integer, intent(in) :: unit
character(kind=CK,len=*), intent(in) :: terminators
integer, intent(out) :: iostat
character(len=*), intent(inout) :: iomsg

Contents

Source Code


Source Code

  subroutine read_undelimited(dtv, unit, terminators, iostat, iomsg)
  !< Read an undelimited string up until end of record or a character from a set of terminators is encountered.
  !<
  !< If a terminator is encountered, the file position will be at that terminating character. If end of record is encountered, the
  !< file remains at end of record.
  class(string),             intent(inout) :: dtv         !< The string.
  integer,                   intent(in)    :: unit        !< Logical unit.
  character(kind=CK, len=*), intent(in)    :: terminators !< Characters that are considered to terminate the string.
                                                          !< Blanks in this string are meaningful.
  integer,                   intent(out)   :: iostat      !< IO status code.
  character(len=*),          intent(inout) :: iomsg       !< IO status message.
  character(kind=CK, len=1)                :: ch          !< A character read.

  dtv%raw = ''
  do
    read(unit, "(A)", iostat=iostat, iomsg=iomsg) ch
    if (is_iostat_eor(iostat)) then
      ! end of record just means end of string. We pass on the condition
      return
    elseif (iostat /= 0) then
      ! something odd happened
      return
    endif
    if (scan(ch, terminators) /= 0) then
      ! change the file position so that the next read sees the terminator
      read(unit, "(TL1)", iostat=iostat, iomsg=iomsg)
      if (iostat /= 0) return
      iostat = 0
      return
    endif
    ! we got a character - append it
    dtv%raw = dtv%raw // ch
  enddo
  endsubroutine read_undelimited