Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
is_regular_file -> is_file
  • Loading branch information
wassup05 committed Aug 12, 2025
commit 95b47ec6ae7cd07dab812ad4a0edad7ea6e0d8f0
8 changes: 4 additions & 4 deletions doc/specs/stdlib_system.md
Original file line number Diff line number Diff line change
Expand Up @@ -497,7 +497,7 @@ Formats all the arguments into a nice error message, utilizing the constructor o

---

## `is_regular_file` - Test if a path is a regular file
## `is_file` - Test if a path is a regular file

### Status

Expand All @@ -511,7 +511,7 @@ It is designed to work across multiple platforms. On Windows, paths with both fo

### Syntax

`result = ` [[stdlib_system(module):is_regular_file(function)]]`(path)`
`result = ` [[stdlib_system(module):is_file(function)]]`(path)`

### Class

Expand All @@ -531,7 +531,7 @@ The function returns a `logical` value:
### Example

```fortran
{!example/system/example_is_regular_file.f90!}
{!example/system/example_is_file.f90!}
```

---
Expand Down Expand Up @@ -584,7 +584,7 @@ Experimental
### Description

This function checks if a specified file system path is a symbolic link to either a file or a directory.
Use [[stdlib_system(module):is_regular_file(function)]] and [[stdlib_system(module):is_directory(function)]] functions
Use [[stdlib_system(module):is_file(function)]] and [[stdlib_system(module):is_directory(function)]] functions
to check further if the link is to a file or a directory respectively.
It is designed to work across multiple platforms. On Windows, paths with both forward `/` and backward `\` slashes are accepted.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are advertising it, would it be reaonable to add a test that checks ./test_file on all systems, and also .\test_file on Windows

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I understand what you mean, do you mean a sort of utility test function to make the tests simpler and extensive by checking both the kinds of paths for all the tests?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it would be useful if the tests tested filename but also ./filename (on all OSes) and .\filename (on Windows only)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't believe that's necessary @perazz, because we haven't written any custom logic for that ourselves, it is how the underlying C functions that do the syscalls behave, so adding tests for such would be like testing the C standard library or the Windows API and not necessarily the test of our own application or library.


Expand Down
2 changes: 1 addition & 1 deletion example/system/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ ADD_EXAMPLE(make_directory)
ADD_EXAMPLE(remove_directory)
ADD_EXAMPLE(cwd)
ADD_EXAMPLE(exists)
ADD_EXAMPLE(is_regular_file)
ADD_EXAMPLE(is_file)
ADD_EXAMPLE(is_directory)
ADD_EXAMPLE(is_symlink)
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
! Demonstrate usage of `is_regular_file`
program example_is_regular_file
use stdlib_system, only: is_regular_file
! Demonstrate usage of `is_file`
program example_is_file
use stdlib_system, only: is_file
implicit none

character(*), parameter :: path = "path/to/check"

! Test if path is a regular file
if (is_regular_file(path)) then
if (is_file(path)) then
print *, "The specified path is a regular file."
else
print *, "The specified path is not a regular file."
end if
end program example_is_regular_file
end program example_is_file
14 changes: 7 additions & 7 deletions src/stdlib_system.F90
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ module stdlib_system
!! version: experimental
!!
!! Tests if a given path is a regular file.
!! ([Specification](../page/specs/stdlib_system.html#is_regular_file))
!! ([Specification](../page/specs/stdlib_system.html#is_file))
!!
!!### Summary
!! Function to evaluate whether a specified path corresponds to a regular file.
Expand All @@ -304,7 +304,7 @@ module stdlib_system
!! It is cross-platform and utilizes native system calls.
!! It supports common operating systems such as Linux, macOS, Windows, and various UNIX-like environments.
!!
public :: is_regular_file
public :: is_file

! CPU clock ticks storage
integer, parameter, private :: TICKS = int64
Expand Down Expand Up @@ -1333,18 +1333,18 @@ end function is_symlink

! checks if path is a regular file.
! It follows symbolic links and returns the status of the `target`.
logical function is_regular_file(path)
logical function is_file(path)
character(len=*), intent(in) :: path

interface
logical(c_bool) function stdlib_is_regular_file(path) bind(C, name='stdlib_is_regular_file')
logical(c_bool) function stdlib_is_file(path) bind(C, name='stdlib_is_file')
import c_char, c_bool
character(kind=c_char) :: path(*)
end function stdlib_is_regular_file
end function stdlib_is_file
end interface

is_regular_file = logical(stdlib_is_regular_file(to_c_char(trim(path))))
end function is_regular_file
is_file = logical(stdlib_is_file(to_c_char(trim(path))))
end function is_file

character function path_sep()
if (OS_TYPE() == OS_WINDOWS) then
Expand Down
2 changes: 1 addition & 1 deletion src/stdlib_system.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ int stdlib_exists(const char* path, int* stat){

// `stat` and `_stat` follow symlinks automatically.
// so no need for winapi functions.
bool stdlib_is_regular_file(const char* path) {
bool stdlib_is_file(const char* path) {
#ifdef _WIN32
struct _stat buf = {0};
return _stat(path, &buf) == 0 && S_ISREG(buf.st_mode);
Expand Down
46 changes: 23 additions & 23 deletions test/system/test_filesystem.f90
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ module test_filesystem
use testdrive, only : new_unittest, unittest_type, error_type, check, skip_test
use stdlib_system, only: is_directory, delete_file, FS_ERROR, FS_ERROR_CODE, &
make_directory, remove_directory, make_directory_all, is_windows, OS_TYPE, &
OS_WINDOWS, get_cwd, set_cwd, operator(/), exists, fs_type_unknown, &
fs_type_regular_file, fs_type_directory, fs_type_symlink, is_regular_file
OS_WINDOWS, get_cwd, set_cwd, operator(/), exists, fs_type_unknown, &
fs_type_regular_file, fs_type_directory, fs_type_symlink, is_file
use stdlib_error, only: state_type, STDLIB_FS_ERROR
use stdlib_strings, only: to_string

Expand All @@ -22,18 +22,18 @@ subroutine collect_suite(testsuite)
new_unittest("fs_exists_reg_file", test_exists_reg_file), &
new_unittest("fs_exists_dir", test_exists_dir), &
new_unittest("fs_exists_symlink", test_exists_symlink), &
new_unittest("fs_is_regular_file", test_is_regular_file), &
new_unittest("fs_is_file", test_is_file), &
new_unittest("fs_is_directory_dir", test_is_directory_dir), &
new_unittest("fs_is_directory_file", test_is_directory_file), &
new_unittest("fs_delete_non_existent", test_delete_file_non_existent), &
new_unittest("fs_delete_existing_file", test_delete_file_existing), &
new_unittest("fs_delete_file_being_dir", test_delete_directory), &
new_unittest("fs_make_dir", test_make_directory), &
new_unittest("fs_make_dir_existing_dir", test_make_directory_existing), &
new_unittest("fs_make_dir_all", test_make_directory_all), &
new_unittest("fs_remove_dir", test_remove_directory), &
new_unittest("fs_remove_dir_non_existent", test_remove_directory_nonexistent), &
new_unittest("fs_cwd", test_cwd) &
new_unittest("fs_delete_file_being_dir", test_delete_directory), &
new_unittest("fs_make_dir", test_make_directory), &
new_unittest("fs_make_dir_existing_dir", test_make_directory_existing), &
new_unittest("fs_make_dir_all", test_make_directory_all), &
new_unittest("fs_remove_dir", test_remove_directory), &
new_unittest("fs_remove_dir_non_existent", test_remove_directory_nonexistent), &
new_unittest("fs_cwd", test_cwd) &
]
end subroutine collect_suite

Expand Down Expand Up @@ -108,23 +108,23 @@ subroutine test_exists_reg_file(error)
if (allocated(error)) return
end subroutine test_exists_reg_file

subroutine test_is_regular_file(error)
subroutine test_is_file(error)
type(error_type), allocatable, intent(out) :: error
character(len=256) :: filename
integer :: ios, iunit
character(len=512) :: msg

logical :: is_file
logical :: is_reg_file

filename = "test_file.txt"

! Create a file
open(newunit=iunit, file=filename, status="replace", iostat=ios, iomsg=msg)
call check(error, ios == 0, "Cannot init test_is_regular_file: " // trim(msg))
call check(error, ios == 0, "Cannot init test_is_file: " // trim(msg))
if (allocated(error)) return

is_file = is_regular_file(filename)
call check(error, is_file, "is_regular_file could not identify a file")
is_reg_file = is_file(filename)
call check(error, is_reg_file, "is_file could not identify a file")

if (allocated(error)) then
! Clean up: remove the file
Expand All @@ -137,7 +137,7 @@ subroutine test_is_regular_file(error)
close(iunit,status='delete',iostat=ios,iomsg=msg)
call check(error, ios == 0, "Cannot delete test file: " // trim(msg))
if (allocated(error)) return
end subroutine test_is_regular_file
end subroutine test_is_file

subroutine test_exists_dir(error)
type(error_type), allocatable, intent(out) :: error
Expand Down Expand Up @@ -293,7 +293,7 @@ subroutine test_is_directory_file(error)
! Create a file
open(newunit=iunit, file=filename, status="replace", iostat=ios, iomsg=msg)
call check(error, ios == 0, "Cannot create test file: " // trim(msg))
if (allocated(error)) return
if (allocated(error)) return

! Verify `is_directory` identifies it as not a directory
result = is_directory(filename)
Expand All @@ -303,7 +303,7 @@ subroutine test_is_directory_file(error)
! Clean up: remove the file
close(iunit,status='delete',iostat=ios,iomsg=msg)
call check(error, ios == 0, "Cannot delete test file: " // trim(msg))
if (allocated(error)) return
if (allocated(error)) return

end subroutine test_is_directory_file

Expand Down Expand Up @@ -378,10 +378,10 @@ subroutine test_delete_directory(error)
! Clean up: remove the empty directory
call execute_command_line('rmdir ' // filename, exitstat=ios, cmdstat=iocmd, cmdmsg=msg)
call check(error, ios==0 .and. iocmd==0, 'Cannot cleanup delete_directory test: '//trim(msg))
if (allocated(error)) return
if (allocated(error)) return

end subroutine test_delete_directory

subroutine test_make_directory(error)
type(error_type), allocatable, intent(out) :: error
type(state_type) :: err
Expand Down Expand Up @@ -471,7 +471,7 @@ subroutine test_remove_directory(error)
call remove_directory(dir_name, err)
call check(error, err%ok(), 'Could not remove directory: '//err%print())

if (allocated(error)) then
if (allocated(error)) then
! clean up: remove the empty directory
call execute_command_line('rmdir ' // dir_name, exitstat=ios, cmdstat=iocmd, cmdmsg=msg)
call check(error, ios==0 .and. iocmd==0, error%message // ' and cannot cleanup make_directory test: '//trim(msg))
Expand Down Expand Up @@ -518,14 +518,14 @@ subroutine test_cwd(error)
call check(error, err%ok(), 'Could not get current working directory: '//err%print())
if (allocated(error)) return

call check(error, pwd2 == abs_dir_name, 'Working directory is wrong, &
call check(error, pwd2 == abs_dir_name, 'Working directory is wrong, &
& expected: '//abs_dir_name//" got: "//pwd2)
if (allocated(error)) return

! cleanup: set the cwd back to the initial value
call set_cwd(pwd1, err)
call check(error, err%ok(), 'Could not clean up cwd test, could not set the cwd back: '//err%print())
if (allocated(error)) then
if (allocated(error)) then
! our cwd now is `./test_directory`
! there is no way of removing the empty test directory
return
Expand Down
Loading