-
Notifications
You must be signed in to change notification settings - Fork 192
Add filesystem interaction #874
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
minhqdao
wants to merge
19
commits into
fortran-lang:master
Choose a base branch
from
minhqdao:add-filesystem-interaction
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 13 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
d760b5f
Extract filesystem interaction from big PR
minhqdao 27b9ece
Add test that includes one dir
minhqdao 0dcfe43
Capitalize f90
minhqdao 96593b5
Let git recognize capitalization of file
minhqdao c1830df
Add is_windows and test it
minhqdao 84f36f1
Use Windows-specific commands and fix tests
minhqdao 0642aff
Check for existence again
minhqdao e58f4b8
Add rm_dir and test it
minhqdao 7e91c7c
Remove all rm -rf
minhqdao 21739b7
Use dir /b on Windows
minhqdao eeeb634
Add mkdir subroutine
minhqdao 9da3ea7
Add path_separator() with tests
minhqdao d913f93
Add docs
minhqdao 9119970
Annotate what we are ending
minhqdao 84fca8b
Obtain os from cmake and python script and make is_windows and path_s…
minhqdao e701d68
Improve tests
minhqdao bf14f0a
Extract stdlib_filesystem
minhqdao ff9242a
Revert changes in stdlib_io.md
minhqdao b0ce565
Fix typo
minhqdao File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
! SPDX-Identifier: MIT | ||
|
||
!> Interaction with the filesystem. | ||
module stdlib_io_filesystem | ||
use stdlib_string_type, only: string_type | ||
implicit none | ||
private | ||
|
||
public :: temp_dir, is_windows, exists, path_separator, list_dir, mkdir, rmdir, run | ||
|
||
character(*), parameter :: temp_dir = 'temp' | ||
|
||
contains | ||
|
||
!> Version: experimental | ||
!> | ||
!> Whether the operating system is Windows. | ||
!> [Specification](../page/specs/stdlib_io.html#is_windows) | ||
logical function is_windows() | ||
character(len=255) :: value | ||
integer :: length, stat | ||
|
||
call get_environment_variable('OSTYPE', value, length, stat) | ||
if (stat == 0 .and. length > 0 .and. (index(value, 'win') > 0 .or. index(value, 'msys') > 0)) then | ||
is_windows = .true.; return | ||
end if | ||
|
||
call get_environment_variable('OS', value, length, stat) | ||
if (stat == 0 .and. length > 0 .and. index(value, 'Windows_NT') > 0) then | ||
is_windows = .true.; return | ||
end if | ||
|
||
is_windows = .false. | ||
end | ||
|
||
!> Version: experimental | ||
!> | ||
!> Returns the path separator for the current operating system. | ||
!> [Specification](../page/specs/stdlib_io.html#path_separator) | ||
character function path_separator() | ||
if (is_windows()) then | ||
path_separator = '\' | ||
else | ||
path_separator = '/' | ||
end if | ||
end | ||
|
||
!> Version: experimental | ||
!> | ||
!> Whether a file or directory exists at the given path. | ||
!> [Specification](../page/specs/stdlib_io.html#exists) | ||
logical function exists(path) | ||
!> Path to a file or directory. | ||
character(len=*), intent(in) :: path | ||
|
||
inquire(file=path, exist=exists) | ||
|
||
#if defined(__INTEL_COMPILER) | ||
if (.not. exists) inquire(directory=path, exist=exists) | ||
#endif | ||
end | ||
|
||
!> Version: experimental | ||
!> | ||
!> List files and directories of a directory. Does not list hidden files. | ||
!> [Specification](../page/specs/stdlib_io.html#list_dir) | ||
subroutine list_dir(dir, files, iostat, iomsg) | ||
!> Directory to list. | ||
character(len=*), intent(in) :: dir | ||
!> List of files and directories. | ||
type(string_type), allocatable, intent(out) :: files(:) | ||
!> Status of listing. | ||
integer, optional, intent(out) :: iostat | ||
!> Error message. | ||
character(len=:), allocatable, optional, intent(out) :: iomsg | ||
|
||
integer :: unit, stat | ||
character(len=256) :: line | ||
character(:), allocatable :: listed_contents | ||
|
||
stat = 0 | ||
|
||
if (.not. exists(temp_dir)) then | ||
call mkdir(temp_dir, stat) | ||
if (stat /= 0) then | ||
if (present(iostat)) iostat = stat | ||
if (present(iomsg)) iomsg = "Failed to create temporary directory '"//temp_dir//"'." | ||
return | ||
end if | ||
end if | ||
|
||
listed_contents = temp_dir//path_separator()//'listed_contents.txt' | ||
|
||
if (is_windows()) then | ||
call run('dir /b '//dir//' > '//listed_contents, stat) | ||
else | ||
call run('ls '//dir//' > '//listed_contents, stat) | ||
end if | ||
if (stat /= 0) then | ||
if (present(iostat)) iostat = stat | ||
if (present(iomsg)) iomsg = "Failed to list files in directory '"//dir//"'." | ||
return | ||
end if | ||
|
||
open(newunit=unit, file=listed_contents, status='old', action='read', iostat=stat) | ||
if (stat /= 0) then | ||
if (present(iostat)) iostat = stat | ||
if (present(iomsg)) iomsg = "Failed to open file '"//listed_contents//"'." | ||
return | ||
end if | ||
|
||
allocate(files(0)) | ||
do | ||
read(unit, '(A)', iostat=stat) line | ||
if (stat /= 0) exit | ||
files = [files, string_type(line)] | ||
end do | ||
close(unit, status="delete") | ||
end | ||
|
||
!> Version: experimental | ||
!> | ||
!> Create a directory. | ||
!> [Specification](../page/specs/stdlib_io.html#mkdir) | ||
subroutine mkdir(dir, iostat, iomsg) | ||
character(len=*), intent(in) :: dir | ||
integer, optional, intent(out) :: iostat | ||
character(len=:), allocatable, optional, intent(out) :: iomsg | ||
|
||
if (is_windows()) then | ||
call run('mkdir '//dir, iostat, iomsg) | ||
else | ||
call run('mkdir -p '//dir, iostat, iomsg) | ||
end if | ||
end | ||
|
||
!> Version: experimental | ||
!> | ||
!> Remove a directory including its contents. | ||
!> [Specification](../page/specs/stdlib_io.html#rmdir) | ||
subroutine rmdir(dir) | ||
character(len=*), intent(in) :: dir | ||
|
||
if (is_windows()) then | ||
call run('rmdir /s/q '//dir) | ||
else | ||
call run('rm -rf '//dir) | ||
end if | ||
end | ||
|
||
!> Version: experimental | ||
!> | ||
!> Run a command in the shell. | ||
!> [Specification](../page/specs/stdlib_io.html#run) | ||
subroutine run(command, iostat, iomsg) | ||
!> Command to run. | ||
character(len=*), intent(in) :: command | ||
!> Status of the operation. | ||
integer, intent(out), optional :: iostat | ||
!> Error message. | ||
character(len=:), allocatable, intent(out), optional :: iomsg | ||
|
||
integer :: exitstat, cmdstat | ||
character(len=256) :: cmdmsg | ||
|
||
if (present(iostat)) iostat = 0 | ||
exitstat = 0; cmdstat = 0 | ||
|
||
call execute_command_line(command, exitstat=exitstat, cmdstat=cmdstat, cmdmsg=cmdmsg) | ||
if (exitstat /= 0 .or. cmdstat /= 0) then | ||
if (present(iostat)) then | ||
if (exitstat /= 0) then | ||
iostat = exitstat | ||
else | ||
iostat = cmdstat | ||
end if | ||
end if | ||
if (present(iomsg) .and. trim(adjustl(cmdmsg)) /= '') iomsg = cmdmsg | ||
end if | ||
end | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.