diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-09-09 02:02:08 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-09-09 02:02:08 -0400 |
| commit | 1fbe2cb5dd1aa4b20411ee0c3b00310677373a55 (patch) | |
| tree | 5362da93fdf255fd08b748e9a72b7179a719f4e0 /builtins | |
| parent | 6752c60f32d0e154e54f30fd2b3e22904e56ea64 (diff) | |
For parsing paths, use nested parens: (./foo), also add some methods
Diffstat (limited to 'builtins')
| -rw-r--r-- | builtins/path.c | 27 | ||||
| -rw-r--r-- | builtins/path.h | 2 |
2 files changed, 27 insertions, 2 deletions
diff --git a/builtins/path.c b/builtins/path.c index ba14c3d8..d5305e30 100644 --- a/builtins/path.c +++ b/builtins/path.c @@ -220,7 +220,7 @@ public void Path$create_directory(Path_t path, int permissions) fail("Could not create directory: %k (%s)", &path, strerror(errno)); } -public Array_t Path$children(Path_t path, bool include_hidden) +static Array_t _filtered_children(Path_t path, bool include_hidden, mode_t filter) { if (Text$matches(path, Pattern("~/{..}"))) path = Paths(Text$format("%s", getenv("HOME")), Text$slice(path, I(2), I(-1))); @@ -240,13 +240,36 @@ public Array_t Path$children(Path_t path, bool include_hidden) continue; if (streq(dir->d_name, ".") || streq(dir->d_name, "..")) continue; - Path_t child = Text$format("%.*s/%s", path_len, path_str, dir->d_name); + + const char *child_str = heap_strf("%.*s/%s", path_len, path_str, dir->d_name); + struct stat sb; + if (stat(child_str, &sb) != 0) + continue; + if (!((sb.st_mode & S_IFMT) & filter)) + continue; + + Path_t child = Text$format("%s%s", child_str, ((sb.st_mode & S_IFMT) == S_IFDIR) ? "/" : ""); // Trailing slash for dirs Array$insert(&children, &child, I(0), sizeof(Path_t)); } closedir(d); return children; } +public Array_t Path$children(Path_t path, bool include_hidden) +{ + return _filtered_children(path, include_hidden, (mode_t)-1); +} + +public Array_t Path$files(Path_t path, bool include_hidden) +{ + return _filtered_children(path, include_hidden, S_IFREG); +} + +public Array_t Path$subdirectories(Path_t path, bool include_hidden) +{ + return _filtered_children(path, include_hidden, S_IFDIR); +} + public const TypeInfo Path$info = { .size=sizeof(Path_t), .align=__alignof__(Path_t), diff --git a/builtins/path.h b/builtins/path.h index 9a37d92d..ea1e99ae 100644 --- a/builtins/path.h +++ b/builtins/path.h @@ -28,6 +28,8 @@ Text_t Path$read(Path_t path); void Path$remove(Path_t path, bool ignore_missing); void Path$create_directory(Path_t path, int permissions); Array_t Path$children(Path_t path, bool include_hidden); +Array_t Path$files(Path_t path, bool include_hidden); +Array_t Path$subdirectories(Path_t path, bool include_hidden); extern const TypeInfo Path$info; |
