following Python (os.path.normpath, os.path.relpath)

This commit is contained in:
Martin Diehl 2023-06-22 22:54:20 +02:00
parent 5053c53ee4
commit fff811edd9
1 changed files with 49 additions and 43 deletions

View File

@ -37,7 +37,7 @@ contains
!> @brief initializes the solver by interpreting the command line arguments. Also writes !> @brief initializes the solver by interpreting the command line arguments. Also writes
!! information on computation to screen !! information on computation to screen
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
subroutine CLI_init subroutine CLI_init()
#include <petsc/finclude/petscsys.h> #include <petsc/finclude/petscsys.h>
#if PETSC_VERSION_MAJOR!=3 || PETSC_VERSION_MINOR<PETSC_MINOR_MIN || PETSC_VERSION_MINOR>PETSC_MINOR_MAX #if PETSC_VERSION_MAJOR!=3 || PETSC_VERSION_MINOR<PETSC_MINOR_MIN || PETSC_VERSION_MINOR>PETSC_MINOR_MAX
@ -45,12 +45,12 @@ subroutine CLI_init
#endif #endif
character(len=:), allocatable :: & character(len=:), allocatable :: &
commandLine, & !< command line call as string commandLine, & !< command line call as string
arg, & !< individual argument arg, & !< individual argument
loadCaseArg, & !< -l argument given to the executable loadCaseArg, & !< -l argument given to the executable
geometryArg, & !< -g argument given to the executable geometryArg, & !< -g argument given to the executable
materialArg, & !< -m argument given to the executable materialArg, & !< -m argument given to the executable
workingDirArg !< -w argument given to the executable workingDirArg !< -w argument given to the executable
integer :: & integer :: &
stat, & stat, &
i i
@ -234,7 +234,7 @@ subroutine setWorkingDirectory(workingDirectoryArg)
workingDirectory = trim(workingDirectory)//'/'//workingDirectoryArg workingDirectory = trim(workingDirectory)//'/'//workingDirectoryArg
end if absolutePath end if absolutePath
workingDirectory = trim(rectifyPath(workingDirectory)) workingDirectory = trim(normpath(workingDirectory))
error = setCWD(trim(workingDirectory)) error = setCWD(trim(workingDirectory))
if (error) then if (error) then
print*, 'ERROR: Invalid Working directory: '//trim(workingDirectory) print*, 'ERROR: Invalid Working directory: '//trim(workingDirectory)
@ -250,8 +250,10 @@ end subroutine setWorkingDirectory
function getSolverJobName() function getSolverJobName()
character(len=:), allocatable :: getSolverJobName character(len=:), allocatable :: getSolverJobName
integer :: posExt,posSep integer :: posExt,posSep
posExt = scan(CLI_geomFile,'.',back=.true.) posExt = scan(CLI_geomFile,'.',back=.true.)
posSep = scan(CLI_geomFile,'/',back=.true.) posSep = scan(CLI_geomFile,'/',back=.true.)
@ -273,12 +275,14 @@ function getPathRelCWD(path,fileType)
character(len=:), allocatable :: getPathRelCWD character(len=:), allocatable :: getPathRelCWD
character(len=*), intent(in) :: path character(len=*), intent(in) :: path
character(len=*), intent(in) :: fileType character(len=*), intent(in) :: fileType
logical :: file_exists logical :: file_exists
external :: quit external :: quit
getPathRelCWD = trim(path) getPathRelCWD = trim(path)
if (scan(getPathRelCWD,'/') /= 1) getPathRelCWD = getCWD()//'/'//trim(getPathRelCWD) if (scan(getPathRelCWD,'/') /= 1) getPathRelCWD = getCWD()//'/'//trim(getPathRelCWD)
getPathRelCWD = trim(makeRelativePath(getCWD(), getPathRelCWD)) getPathRelCWD = trim(relpath(getPathRelCWD,getCWD()))
inquire(file=getPathRelCWD, exist=file_exists) inquire(file=getPathRelCWD, exist=file_exists)
if (.not. file_exists) then if (.not. file_exists) then
@ -293,76 +297,78 @@ end function getPathRelCWD
!> @brief Remove ../, /./, and // from path. !> @brief Remove ../, /./, and // from path.
!> @details Works only if absolute path is given. !> @details Works only if absolute path is given.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function rectifyPath(path) function normpath(path)
character(len=*), intent(in) :: path character(len=*), intent(in) :: path
character(len=:), allocatable :: rectifyPath character(len=:), allocatable :: normpath
integer :: i,j,k,l integer :: i,j,k,l
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! remove /./ from path ! remove /./ from path
rectifyPath = trim(path) normpath = trim(path)
l = len_trim(rectifyPath) l = len_trim(normpath)
do i = l,3,-1 do i = l,3,-1
if (rectifyPath(i-2:i) == '/./') rectifyPath(i-1:l) = rectifyPath(i+1:l)//' ' if (normpath(i-2:i) == '/./') normpath(i-1:l) = normpath(i+1:l)//' '
end do end do
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! remove // from path ! remove // from path
l = len_trim(rectifyPath) l = len_trim(normpath)
do i = l,2,-1 do i = l,2,-1
if (rectifyPath(i-1:i) == '//') rectifyPath(i-1:l) = rectifyPath(i:l)//' ' if (normpath(i-1:i) == '//') normpath(i-1:l) = normpath(i:l)//' '
end do end do
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
! remove ../ and corresponding directory from rectifyPath ! remove ../ and corresponding directory from path
l = len_trim(rectifyPath) l = len_trim(normpath)
i = index(rectifyPath(i:l),'../') i = index(normpath(i:l),'../')
j = 0 j = 0
do while (i > j) do while (i > j)
j = scan(rectifyPath(1:i-2),'/',back=.true.) j = scan(normpath(1:i-2),'/',back=.true.)
rectifyPath(j+1:l) = rectifyPath(i+3:l)//repeat(' ',2+i-j) normpath(j+1:l) = normpath(i+3:l)//repeat(' ',2+i-j)
if (rectifyPath(j+1:j+1) == '/') then !search for '//' that appear in case of XXX/../../XXX if (normpath(j+1:j+1) == '/') then !search for '//' that appear in case of XXX/../../XXX
k = len_trim(rectifyPath) k = len_trim(normpath)
rectifyPath(j+1:k-1) = rectifyPath(j+2:k) normpath(j+1:k-1) = normpath(j+2:k)
rectifyPath(k:k) = ' ' normpath(k:k) = ' '
end if end if
i = j+index(rectifyPath(j+1:l),'../') i = j+index(normpath(j+1:l),'../')
end do end do
if (len_trim(rectifyPath) == 0) rectifyPath = '/' if (len_trim(normpath) == 0) normpath = '/'
rectifyPath = trim(rectifyPath) normpath = trim(normpath)
end function rectifyPath end function normpath
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
!> @brief Determine relative path from absolute a to absolute b. !> @brief Determine relative path.
!-------------------------------------------------------------------------------------------------- !--------------------------------------------------------------------------------------------------
function makeRelativePath(a,b) function relpath(path,start)
character(len=*), intent(in) :: a,b character(len=*), intent(in) :: start,path
character(len=:), allocatable :: makeRelativePath character(len=:), allocatable :: relpath
character(len=:), allocatable :: a_cleaned,b_cleaned character(len=:), allocatable :: start_cleaned,path_cleaned
integer :: i,posLastCommonSlash,remainingSlashes integer :: i,posLastCommonSlash,remainingSlashes
posLastCommonSlash = 0 posLastCommonSlash = 0
remainingSlashes = 0 remainingSlashes = 0
a_cleaned = rectifyPath(trim(a)//'/') start_cleaned = normpath(trim(start)//'/')
b_cleaned = rectifyPath(b) path_cleaned = normpath(path)
do i = 1, min(len_trim(a_cleaned),len_trim(b_cleaned)) do i = 1, min(len_trim(start_cleaned),len_trim(path_cleaned))
if (a_cleaned(i:i) /= b_cleaned(i:i)) exit if (start_cleaned(i:i) /= path_cleaned(i:i)) exit
if (a_cleaned(i:i) == '/') posLastCommonSlash = i if (start_cleaned(i:i) == '/') posLastCommonSlash = i
end do end do
do i = posLastCommonSlash+1,len_trim(a_cleaned) do i = posLastCommonSlash+1,len_trim(start_cleaned)
if (a_cleaned(i:i) == '/') remainingSlashes = remainingSlashes + 1 if (start_cleaned(i:i) == '/') remainingSlashes = remainingSlashes + 1
end do end do
makeRelativePath = repeat('..'//'/',remainingSlashes)//b_cleaned(posLastCommonSlash+1:len_trim(b_cleaned)) relpath = repeat('..'//'/',remainingSlashes)//path_cleaned(posLastCommonSlash+1:len_trim(path_cleaned))
end function makeRelativePath end function relpath
end module CLI end module CLI