split_to_lines Subroutine

private subroutine split_to_lines(text, lines, n_lines)

Split a newline-separated buffer into a fixed-len character array (one record per line, trailing CR stripped) for internal-file reads + the schema line walker.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: text
character(len=:), intent(out), allocatable :: lines(:)
integer, intent(out) :: n_lines

Called by

proc~~split_to_lines~~CalledByGraph proc~split_to_lines split_to_lines proc~read_config_from_string_impl read_config_from_string_impl proc~read_config_from_string_impl->proc~split_to_lines proc~read_config_from_string read_config_from_string proc~read_config_from_string->proc~read_config_from_string_impl proc~build_pending_handle build_pending_handle proc~build_pending_handle->proc~read_config_from_string proc~rdb_ocean_create_from_string rdb_ocean_create_from_string proc~rdb_ocean_create_from_string->proc~build_pending_handle proc~rdb_ocean_create_pending rdb_ocean_create_pending proc~rdb_ocean_create_pending->proc~build_pending_handle

Variables

Type Visibility Attributes Name Initial
character(len=1), private :: c
integer, private :: cur
integer, private :: i
integer, private :: maxlen
integer, private :: nl
integer, private :: start

Source Code

   subroutine split_to_lines(text, lines, n_lines)
      !! Split a newline-separated buffer into a fixed-len character array
      !! (one record per line, trailing CR stripped) for internal-file
      !! reads + the schema line walker.
      character(len=*), intent(in) :: text
      character(len=:), allocatable, intent(out) :: lines(:)
      integer, intent(out) :: n_lines

      integer :: i, start, maxlen, cur, nl
      character(len=1) :: c

      ! First pass: count records + longest line.
      nl = 1
      maxlen = 0
      cur = 0
      do i = 1, len(text)
         c = text(i:i)
         if (c == achar(10)) then
            nl = nl + 1
            maxlen = max(maxlen, cur)
            cur = 0
         else if (c /= achar(13)) then
            cur = cur + 1
         end if
      end do
      maxlen = max(maxlen, cur, 1)

      allocate (character(len=maxlen) :: lines(nl))
      ! Blank-fill via a SECTION, not `lines = ""`.  `lines` has a DEFERRED
      ! length, so whole-variable intrinsic assignment from a zero-length
      ! scalar re-allocates it with len = 0 (F2018 10.2.1.3p3) — ifx does
      ! exactly that, and every record then parses as empty.  A section
      ! designator is not an allocatable variable, so it blank-pads in place.
      lines(:) = ""

      ! Second pass: copy each record.
      n_lines = 0
      start = 1
      cur = 0
      do i = 1, len(text)
         c = text(i:i)
         if (c == achar(10)) then
            n_lines = n_lines + 1
            if (cur > 0) lines(n_lines) = text(start:start + cur - 1)
            start = i + 1
            cur = 0
         else if (c /= achar(13)) then
            ! CR is skipped (a trailing CR before LF is excluded because
            ! `cur` counts only content chars and `start` marks the first).
            if (cur == 0) start = i
            cur = cur + 1
         end if
      end do
      ! Trailing record (no final newline).
      n_lines = n_lines + 1
      if (cur > 0) lines(n_lines) = text(start:start + cur - 1)
   end subroutine split_to_lines