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.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | text | |||
| character(len=:), | intent(out), | allocatable | :: | lines(:) | ||
| integer, | intent(out) | :: | n_lines |
| 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 |
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