run_argv Subroutine

public subroutine run_argv(args, echo, exitstat, verbose, redirect)

Arguments

Type IntentOptional Attributes Name
type(string_t), intent(in) :: args(:)
logical, intent(in), optional :: echo
integer, intent(out), optional :: exitstat
logical, intent(in), optional :: verbose
character(len=*), intent(in), optional :: redirect

Source Code

subroutine run_argv(args,echo,exitstat,verbose,redirect)
    type(string_t), intent(in) :: args(:)
    logical,intent(in),optional  :: echo
    integer, intent(out),optional :: exitstat
    logical, intent(in), optional :: verbose
    character(*), intent(in), optional :: redirect

    character(:), allocatable :: command
    character(:), allocatable :: joined
    character(:), allocatable :: redirect_file
    character(:), allocatable :: line
    character(len=256) :: iomsg
    logical :: echo_local, verbose_local
    integer :: stat, fh, iostat, i

    command = string_cat(args, " ")

    if(present(echo))then
       echo_local=echo
    else
       echo_local=.true.
    end if

    if(present(verbose))then
        verbose_local=verbose
    else
        verbose_local=.true.
    end if

    if (present(redirect)) then
        redirect_file = redirect
    else
        if(verbose_local)then
            redirect_file = ""
        else
            if (os_is_unix()) then
                redirect_file = "/dev/null"
            else
                redirect_file = "NUL"
            end if
        end if
    end if

    if(echo_local) print *, '+ ', command

    if (size(args) < 1) then
        stat = 0
#ifndef FPM_BOOTSTRAP
    else
        joined = ""
        do i = 1, size(args)
            joined = joined//args(i)%s//c_null_char
        end do
        stat = c_run_argv(joined//c_null_char, int(size(args), c_int), &
            redirect_file//c_null_char)
#else
    else
        call run(command, echo=.false., verbose=verbose_local, redirect=redirect_file, exitstat=stat)
#endif
    end if

    ! Fall back to the shell if the argv spawn was unavailable or failed (stat < 0).
    if (stat < 0) then
        call run(command, echo=.false., verbose=verbose_local, redirect=redirect_file, exitstat=stat)
    end if

    ! Some posix_spawnp implementations start the child anyway and report a
    ! missing program only as its exit status 127.
    if (stat == 127 .and. os_is_unix()) then
        if (command_not_found(command)) then
            write(*,'(a)')'<ERROR>:failed command '//command
            call fpm_stop(1, "Could not execute '"//command_program(command)//"': program not found on PATH."//new_line('a')// &
                "  Check that it is installed and on your PATH, or set it explicitly with"//new_line('a')// &
                "  --compiler / FPM_FC (use FPM_CC / FPM_AR for the C compiler / archiver).")
        end if
    end if

    if (verbose_local.and.present(redirect)) then

        open(newunit=fh,file=redirect,status='old',iostat=iostat,iomsg=iomsg)
        if(iostat == 0)then
           do
               call getline(fh, line, iostat)
               if (iostat /= 0) exit
               write(*,'(A)') trim(line)
           end do
        else
           write(*,'(A)') trim(iomsg)
        endif

        close(fh)

    end if

    if (present(exitstat)) then
        exitstat = stat
    elseif (stat /= 0) then
        call fpm_stop(stat,'*run_argv*: Command '//command//' returned a non-zero status code')
    end if

end subroutine run_argv