Skip to content

Commit 38e2337

Browse files
committed
implement is_directory
1 parent d724658 commit 38e2337

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

src/stdlib_system.F90

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module stdlib_system
22
use, intrinsic :: iso_c_binding, only : c_int, c_long, c_null_ptr, c_int64_t
3-
use stdlib_kinds, only: int64, dp
3+
use stdlib_kinds, only: int64, dp, c_bool, c_char
4+
use stdlib_strings, only: to_c_char
45
implicit none
56
private
67
public :: sleep
@@ -81,6 +82,22 @@ module stdlib_system
8182
public :: elapsed
8283
public :: is_windows
8384

85+
!! version: experimental
86+
!!
87+
!! Tests if a given path matches an existing directory.
88+
!! ([Specification](../page/specs/stdlib_io.html#is_directory-test-if-a-path-is-a-directory))
89+
!!
90+
!!### Summary
91+
!! Function to evaluate whether a specified path corresponds to an existing directory.
92+
!!
93+
!!### Description
94+
!!
95+
!! This function checks if a given file system path is a directory. It is cross-platform and avoids reliance
96+
!! on external C libraries by utilizing system calls. It supports common operating systems such as Linux, macOS,
97+
!! Windows, and various UNIX-like environments. On unsupported operating systems, the function will return `.false.`.
98+
!!
99+
public :: is_directory
100+
84101
! CPU clock ticks storage
85102
integer, parameter, private :: TICKS = int64
86103
integer, parameter, private :: RTICKS = dp
@@ -618,4 +635,23 @@ pure function OS_NAME(os)
618635
end select
619636
end function OS_NAME
620637

638+
!! Tests if a given path matches an existing directory.
639+
!! Cross-platform implementation without using external C libraries.
640+
logical function is_directory(path)
641+
!> Input path to evaluate
642+
character(*), intent(in) :: path
643+
644+
interface
645+
646+
logical(c_bool) function stdlib_is_directory(path) bind(c, name="stdlib_is_directory")
647+
import c_bool, c_char
648+
character(kind=c_char), intent(in) :: path(*)
649+
end function stdlib_is_directory
650+
651+
end interface
652+
653+
is_directory = logical(stdlib_is_directory(to_c_char(path)))
654+
655+
end function is_directory
656+
621657
end module stdlib_system

src/stdlib_system_subprocess.F90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
submodule (stdlib_system) stdlib_system_subprocess
22
use iso_c_binding
33
use iso_fortran_env, only: int64, real64
4-
use stdlib_strings, only: to_c_char, join
4+
use stdlib_strings, only: join
55
use stdlib_linalg_state, only: linalg_state_type, LINALG_ERROR, linalg_error_handling
66
implicit none(type, external)
77

src/stdlib_system_subprocess.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#else
1111
#define _POSIX_C_SOURCE 199309L
1212
#include <sys/wait.h>
13+
#include <sys/stat.h>
1314
#include <unistd.h>
1415
#include <time.h>
1516
#include <errno.h>
@@ -220,6 +221,12 @@ bool process_kill_windows(stdlib_pid pid) {
220221
return true;
221222
}
222223

224+
// Check if input path is a directory
225+
bool stdlib_is_directory_windows(const char *path) {
226+
DWORD attrs = GetFileAttributesA(path);
227+
return (attrs != INVALID_FILE_ATTRIBUTES) // Path exists
228+
&& (attrs & FILE_ATTRIBUTE_DIRECTORY); // Path is a directory
229+
}
223230

224231
#else // _WIN32
225232

@@ -292,12 +299,29 @@ void process_create_posix(stdlib_pid* pid)
292299
(*pid) = (stdlib_pid) fork();
293300
}
294301

302+
// On UNIX systems: check if input path is a directory
303+
bool stdlib_is_directory_posix(const char *path) {
304+
struct stat sb;
305+
return stat(path, &sb) == 0 && S_ISDIR(sb.st_mode);
306+
}
307+
295308
#endif // _WIN32
296309

297310
/////////////////////////////////////////////////////////////////////////////////////
298311
// Cross-platform interface
299312
/////////////////////////////////////////////////////////////////////////////////////
300313

314+
// Cross-platform interface: query directory state
315+
bool stdlib_is_directory(const char *path) {
316+
// Invalid input
317+
if (path == NULL || strlen(path) == 0) return false;
318+
#ifdef _WIN32
319+
return stdlib_is_directory_windows(path);
320+
#else
321+
return stdlib_is_directory_posix(path);
322+
#endif // _WIN32
323+
}
324+
301325
// Create or fork process
302326
void process_create(const char* cmd, const char* stdin_stream, const char* stdin_file,
303327
const char* stdout_file, const char* stderr_file,

0 commit comments

Comments
 (0)