inject_names_into_cmd Function

public function inject_names_into_cmd(prefix, rest, names) result(out)

Inject target names into a command line while respecting a -- delimiter.

fpm run and fpm test accept optional name patterns. This helper inserts those names into the right location: - after the prefix and any existing fpm options, - before a -- delimiter (if present), so that program arguments remain attached to the executed program.

Arguments

Type IntentOptional Attributes Name
character(len=*), intent(in) :: prefix

Prefix up to and including the subcommand.

character(len=*), intent(in) :: rest

Remaining arguments after the subcommand.

character(len=*), intent(in) :: names

Space-separated names to inject.

Return Value character(len=:), allocatable


Called by

proc~~inject_names_into_cmd~~CalledByGraph proc~inject_names_into_cmd inject_names_into_cmd proc~build_run_command build_run_command proc~build_run_command->proc~inject_names_into_cmd proc~watcher_run watcher_t%watcher_run proc~watcher_run->proc~build_run_command

Source Code

   function inject_names_into_cmd(prefix, rest, names) result(out)
      character(len=*), intent(in) :: prefix
      !! Prefix up to and including the subcommand.
      character(len=*), intent(in) :: rest
      !! Remaining arguments after the subcommand.
      character(len=*), intent(in) :: names
      !! Space-separated names to inject.
      character(len=:), allocatable :: out

      character(len=:), allocatable :: p, r, n, before, after
      integer :: dd

      p = trim(prefix)
      r = adjustl(trim(rest))
      n = trim(names)

      if (len_trim(p) == 0) then
         out = ""
         return
      end if

      if (len_trim(n) == 0) then
         if (len_trim(r) == 0) then
            out = p
         else
            out = p // " " // r
         end if
         return
      end if

      dd = find_double_dash_delim(r)
      if (dd > 0) then
         if (dd > 1) then
            before = trim(r(1:dd-1))
         else
            before = ""
         end if
         after = trim(adjustl(r(dd:)))
      else
         before = trim(r)
         after = ""
      end if

      out = p
      if (len_trim(before) > 0) out = out // " " // before
      out = out // " " // n
      if (len_trim(after) > 0) out = out // " " // after

   contains

      pure integer function find_double_dash_delim(str) result(pos)
         character(len=*), intent(in) :: str
         integer :: i, n
         pos = 0
         n = len_trim(str)
         if (n < 2) return
         do i = 1, n-1
            if (str(i:i+1) == "--") then
               if (is_boundary(str, i-1) .and. is_boundary(str, i+2)) then
                  pos = i
                  return
               end if
            end if
         end do
      end function find_double_dash_delim

      pure logical function is_boundary(str, j) result(ok)
         character(len=*), intent(in) :: str
         integer, intent(in) :: j
         integer :: n
         n = len_trim(str)
         if (j < 1) then
            ok = .true.
         else if (j > n) then
            ok = .true.
         else
            ok = (str(j:j) == " " .or. str(j:j) == char(9))
         end if
      end function is_boundary

   end function inject_names_into_cmd