Parse the &ocean_diag_nml diags selection string into structured
entries. Entries are whitespace/comma-separated; within an entry,
colon-separated attributes are self-identifying (order-free):
off -> skip the diagnosticinstant/mean/max/min -> time-operator override<int><unit> (s/m/h/d) -> cadence overrideThe first colon field is always the diagnostic name (case-sensitive, matched against registered / catalog names). Attribute matching is case-insensitive. An empty/blank string yields a zero-length array (the bit-identical default). An unrecognised attribute fails loud.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | spec |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| character(len=len), | private | :: | buf | ||||
| integer, | private | :: | i | ||||
| integer, | private | :: | j | ||||
| integer, | private | :: | k | ||||
| integer, | private | :: | n | ||||
| integer, | private | :: | ntok |
function parse_diag_spec(spec) result(specs) !! Parse the `&ocean_diag_nml diags` selection string into structured !! entries. Entries are whitespace/comma-separated; within an entry, !! colon-separated attributes are self-identifying (order-free): !! !! * `off` -> skip the diagnostic !! * `instant`/`mean`/`max`/`min` -> time-operator override !! * `<int><unit>` (s/m/h/d) -> cadence override !! !! The first colon field is always the diagnostic name (case-sensitive, !! matched against registered / catalog names). Attribute matching is !! case-insensitive. An empty/blank string yields a zero-length array !! (the bit-identical default). An unrecognised attribute fails loud. character(len=*), intent(in) :: spec type(diag_spec_t), allocatable :: specs(:) character(len=len(spec)) :: buf integer :: i, j, n, ntok, k ! Normalise commas to spaces so both separators work. buf = spec do i = 1, len(buf) if (buf(i:i) == ",") buf(i:i) = " " end do n = len_trim(buf) ! Pass 1: count whitespace-delimited tokens. ntok = 0 i = 1 do while (i <= n) if (buf(i:i) == " ") then i = i + 1 cycle end if ntok = ntok + 1 do while (i <= n) if (buf(i:i) == " ") exit i = i + 1 end do end do allocate (specs(ntok)) if (ntok == 0) return ! Pass 2: parse each token into name + attributes. k = 0 i = 1 do while (i <= n) if (buf(i:i) == " ") then i = i + 1 cycle end if j = i do while (j <= n) if (buf(j:j) == " ") exit j = j + 1 end do k = k + 1 call parse_one_spec_token(buf(i:j - 1), specs(k)) i = j + 1 end do end function parse_diag_spec