escape_shell_arg Function

public function escape_shell_arg(arg) result(escaped)

Arguments

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

Return Value character(len=:), allocatable


Source Code

    function escape_shell_arg(arg) result(escaped)
        character(len=*), intent(in) :: arg
        character(len=:), allocatable :: escaped
        integer :: i, n
        character(len=1) :: ch
        logical :: is_windows_path

        ! For use inside double quotes, we only need to escape:
        ! " (double quote), \ (backslash), $ (dollar), ` (backtick)
        ! We don't escape spaces since we're inside quotes

        ! On Windows, don't escape backslashes if this looks like a path
        is_windows_path = .false.
        if (get_os_type() == OS_WINDOWS) then
            ! Check if this looks like a Windows path (e.g., C:\ or \\network)
            if (len_trim(arg) >= 3) then
                if ((arg(2:2) == ':' .and. arg(3:3) == '\') .or. &
                    (arg(1:2) == '\\')) then
                    is_windows_path = .true.
                end if
            end if
        end if

        ! Count how many characters we need
        n = 0
        do i = 1, len_trim(arg)
            ch = arg(i:i)
            if (ch == '"' .or. (ch == '\' .and. .not. is_windows_path) .or. &
                ch == '$' .or. ch == '`') then
                n = n + 2  ! Need to escape these characters
            else
                n = n + 1
            end if
        end do

        ! Allocate result
        allocate (character(len=n) :: escaped)

        ! Build escaped string
        n = 0
        do i = 1, len_trim(arg)
            ch = arg(i:i)
            if (ch == '"' .or. (ch == '\' .and. .not. is_windows_path) .or. &
                ch == '$' .or. ch == '`') then
                n = n + 1
                escaped(n:n) = '\'
                n = n + 1
                escaped(n:n) = ch
            else
                n = n + 1
                escaped(n:n) = ch
            end if
        end do

        ! Trim to actual length
        escaped = escaped(1:n)
    end function escape_shell_arg