Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(string), | intent(out) | :: | dtv | |||
integer, | intent(in) | :: | unit | |||
character(kind=CK, len=1), | intent(in) | :: | delim | |||
integer, | intent(out) | :: | iostat | |||
character(kind=CK, len=*), | intent(inout) | :: | iomsg |
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