Split a command line into <fpm subcmd> prefix and remaining arguments.
This is used to support name injection for fpm run/fpm test:
the injected names are inserted after prefix and before the rest,
while respecting a -- delimiter.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| character(len=*), | intent(in) | :: | full |
Full command string. |
||
| character(len=:), | intent(out), | allocatable | :: | prefix |
Prefix up to and including the subcommand token. |
|
| character(len=:), | intent(out), | allocatable | :: | rest |
Remaining arguments after the subcommand. |
subroutine split_cmd_after_subcmd(full, prefix, rest) character(len=*), intent(in) :: full !! Full command string. character(len=:), allocatable, intent(out) :: prefix !! Prefix up to and including the subcommand token. character(len=:), allocatable, intent(out) :: rest !! Remaining arguments after the subcommand. character(len=:), allocatable :: s integer :: p_fpm_end, p_sub_start, p_sub_end s = adjustl(trim(full)) prefix = "" rest = "" if (len_trim(s) == 0) return if (.not. starts_with_token(s, "fpm")) return p_fpm_end = token_end(s, 1) p_sub_start = next_token_start(s, p_fpm_end + 1) if (p_sub_start == 0) return p_sub_end = token_end(s, p_sub_start) prefix = trim(s(1:p_sub_end)) if (p_sub_end < len_trim(s)) then rest = adjustl(s(p_sub_end+1:)) else rest = "" end if contains pure logical function starts_with_token(str, tok) result(ok) character(len=*), intent(in) :: str, tok integer :: e, n ok = .false. n = len_trim(tok) if (n == 0) return if (len_trim(str) < n) return if (str(1:n) /= tok(1:n)) return e = token_end(str, 1) ok = (e == n) end function starts_with_token pure integer function next_token_start(str, i) result(pos) character(len=*), intent(in) :: str integer, intent(in) :: i integer :: k, n pos = 0 n = len_trim(str) k = max(1, i) do while (k <= n) if (str(k:k) /= " " .and. str(k:k) /= char(9)) then pos = k return end if k = k + 1 end do end function next_token_start pure integer function token_end(str, i) result(pos) character(len=*), intent(in) :: str integer, intent(in) :: i integer :: k, n pos = 0 n = len_trim(str) if (i < 1 .or. i > n) return k = i do while (k <= n) if (str(k:k) == " " .or. str(k:k) == char(9)) then pos = k - 1 return end if k = k + 1 end do pos = n end function token_end end subroutine split_cmd_after_subcmd